// 1. 第一步,使用VueX,首先要引入,而且在模块化系统中还要使用Vue.use(Vuex)
// 2. 第二步, 实例化一个Vuex.Store, 从而获得一个store对象,这个store是Vuex的核心,即仓库,其管理着应用的大部分共享状态
const store = new Vuex.Store({
state: {
count: 0,
},
getters: {// 通过store暴露的getters访问,组件内部可通过this.$store.getters访问相关属性
// 一些依赖某些状态的常用计算,可以用getter来表明这些属性,类似于计算属性,因为Vuex的状态是响应式的,因此,getter也需要满足响应规则,但是getter会缓存计算的结果,只有当其依赖的状态发生变化时才会重新计算
doubleCount: function(state){
return state.count * 2;
},
funcCount: function(state) {// getter也可以返回函数,以函数调用的形式使用,此时每次都是重新调用,而不是用缓存
return function(scale) {
return state.count * scale;
}
},
},
mutations: {// store和全局对象的区别:(1)其state是响应式的,状态改变相应的视图也改变;(2)只能通过commit一个mutation来修改state
increment: function(state, payload) {
state.count++;
console.log('mutation的第二个参数是载荷', payload);
}
},
actions: {// mutation只能是同步操作,不能进行异步操作,因为在mutation中进行异步操作会带来同步/互斥问题,即不知道哪个异步先完成,从而不知道状态以哪个为准
// action可以进行异步操作,action和mutation的区别在于:(1)action不直接更新状态,而是commit一个mutation去改变状态
// (2)action可以做异步操作,其实就是可以在action内部执行异步,选择异步结束后去commit一个mutation从而更新状态
// action通过store的dispatch来暴露出来,在组件内部可使用this.$store.dispatch来分发action
increment: function(context) {
setTimeout(function() {
context.commit('increment', {info: 'action trigger'});
}, 1000);
}
}
});
var TestVuex = {// 4. 第四步,可以在某个组件内部使用$store来访问state中的各个状态,同时在某个方法中通过$store.commit的方式来触发一个状态的改变
template: `
<div>
vuex中的count: {{this.$store.state.count}}
<div @click="changeCount" style="width: 100px; height: 50px; backgroundColor: red">
点击触发状态改变
</div>
</div>
`,
methods: {
changeCount: function() {
this.$store.commit('increment');
console.log('change后的状态', this.$store.state.count);
console.log('change');
console.log('getter double', this.$store.getters.doubleCount);
console.log('以函数调用的形式调用getter', this.$store.getters.funcCount(5));
this.$store.dispatch('increment')
}
}
};
new Vue({
el: '#root',
data: {
test: 'testVueX',
},
store: store, // 3. 第三步,在组件实例中注入store,为了让应用的全部组件都可用,可在根实例中注入
components: {
'test-vuex': TestVuex,
}
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="root">
<div>{{ test }}</div>
<test-vuex></test-vuex>
</div>