有User.js
类和用户对象(user = new User();
)。
user
对象正在所有嵌套组件中使用。在User
类中,有很多重要的方法。
如何简单地在任何组件中使用/访问this.user
或this.$user
及其方法?
1-解决方案 (临时工作解决方案):在vuex的商店中设置user
,并在所有组件的{{ 1}}:
data
缺点:应在每个组件中添加。注意:组件太多。
2-解决方案 :将用户添加到Vue的原型中,例如插件:
data(){
return {
user:this.$store.state.user
}
}
缺点:Vue.prototype.$user = user
的数据更改时,在DOM元素(UI)中不会影响。
3-解决方案 :放入组件的道具。
缺点:应在每个组件中添加。注意:同样,组件太多。
我发现的所有解决方案都存在问题,尤其是随着项目的规模越来越大。
任何建议和解决方案将不胜感激!
答案 0 :(得分:4)
基于@Denis的答案,特别是建议3 ,这是UserPlugin.js
:
import store from '@/store/store';
import User from './User';
const UserPlugin = {
install(Vue) {
const $user = new User();
window.$user = $user;
store.commit('setUser', $user);
Vue.mixin({
computed: {
$user() {
return store.state.user;
}
}
});
}
};
export default UserPlugin;
和main.js
:
import UserPlugin from './common/UserPlugin';
Vue.use(UserPlugin);
new Vue({
render: h => h(App)
}).$mount('#app');
为了进一步使用,我发布了一个小型图书馆来解决这些问题:
答案 1 :(得分:3)
getters
与mapGetters
结合使用,以将用户包括在每个组件的计算属性中。Vuex
getters: {
// ...
getUser: (state, getters) => {
return getters.user
}
}
组件
import { mapGetters } from 'vuex'
computed: {
...mapGetters([getUser])
}
Vue
// When using CommonJS via Browserify or Webpack
const Vue = require('vue')
const UserPlug = require('./user-watcher-plugin')
// Don't forget to call this
Vue.use(UserPlug)
user-watcher-plugin.js
const UserPlug = {
install(Vue, options) {
// We call Vue.mixin() here to inject functionality into all components.
Vue.watch: 'user'
}
};
export default UserPlug;
user
作为插件Vue
// When using CommonJS via Browserify or Webpack
const Vue = require('vue')
const UserPlug = require('./user-watcher-plugin')
// Don't forget to call this
Vue.use(UserPlug)
user-watcher-plugin.js
const UserPlug = {
install(Vue, options) {
// We call Vue.mixin() here to inject functionality into all components.
Vue.mixin({
computed: {
user: function() {
return this.$store.state.user
}
}
})
}
};
export default UserPlug;
答案 2 :(得分:1)
您可以使用mixins将User.js
添加到您的根组件中,例如
import userLib from './User';
//User.js path should correct
然后
var app = new Vue({
router,
mixins: [
userLib
],
//.....
});
之后,您可以在任何组件中使用这些User
方法中的任何一个
this.$parent.userClassMehtod();
或是否有数据访问
this.$parent.userClassData;
最后不要忘记在export default{//..}
中添加User.js
注意:仅当您将User.js
的所有方法导出到export default
答案 3 :(得分:1)
假设您实际上并没有在每个组件中使用user
的所有方法/属性,而是每次都使用它们的子集,我看不出解决方案1和2对您不起作用的任何原因,因为不必将整个user
对象传递给每个组件。
比方说,您的对象User
具有一些属性(a1,a2,a3等)和方法(m1,m2,m3 ...)。如果某个组件仅需要其中的一部分(例如a1,a2,m1,m2,m3),则使用Vuex,您可以使用映射函数(mapState,mapGetters,mapMutations和mapActions)从user
<获取确切的信息/ p>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState('user', [ 'a1' ]),
...mapGetters('user', [ 'a2' ])
},
methods: {
...mapMutations('user', [ 'm1' ]),
...mapActions('user', [ 'm2', 'm3' ])
}
}
对于解决方案2(使用原型),要在user
数据更改时进行组件更新,可以通过methods
将必要的数据映射到组件。
export default {
methods: {
userA1() {
return this.$user.attributes.a1;
},
userM1() {
this.$user.methods.m1();
}
// and so on
}
}
更好的是,您可以创建mixin来显式映射user
中的数据,并重用mixins以避免组件中的重复代码。它可以同时应用于Vuex解决方案和原型解决方案。
// mixin1:
const mixin1 = {
computed: {
...mapState('user', [ 'a1' ]),
},
methods: {
...mapMutations('user', [ 'm1' ])
}
}
// mixin2:
const mixin2 = {
computed: {
...mapGetters('user', [ 'a2' ]),
},
methods: {
...mapActions('user', [ 'm2', 'm3' ])
}
}
// component1
export default {
mixins: [ mixin1 ]
}
// component 2
export default {
mixins: [ mixin1, mixin2 ]
}
但是,如果您确实需要将整个对象user
传递给每个组件,则无能为力。相反,您应该查看实现,并查看是否有更好的方法可以将对象分解为更小的有意义的对象。
答案 4 :(得分:1)
我刚刚创建了最小的codesandbox,以清除关于dependency Injection
如何工作的想法。
答案 5 :(得分:-3)
您可以拥有第二个Vue实例并声明一个反应性属性。