为了让组件更容易拿到数据和方法,我们会使用到vuex插件。
Vuex是一个专为Vue.js应用程序开发的状态管理模式。
Vuex的核心是store(仓库),store基本上就是一个容器,它包含着你的应用中大部分的状态 (state)
整体上来看,难度并不大,写法都是参考vue,但是很多单词都换了,所以需要额外记忆和熟练使用。
export default new Vuex.Store({
state: () => {
//类似于vue的data
return {
a: 1,
b: 1,
timer: null,
};
},
getters: {
//类似于vue的computed
// 函数中的第一参数: state -> 当前store实例中的state对象
// 函数中的第二参数: getters -> 当前store实例中的getters对象
doubleA: (state) => {
return state.a * 2;
},
doubleB(state) {
return state.b * 2;
},
doubleBoth: function (state, getters) {
return getters.doubleA + getters.doubleB;
},
},
mutations: {
//类似于vue的methods,但只写同步方法
//第一个参数就是state
//第二个参数是你需要传递的参数
addA(state) {
state.a++;
},
addB(state) {
state.b++;
},
addAN(state, pl) {
state.a += pl;
},
},
actions: {
//类似vue的methods,一般写异步方法
//第一个参数context其实就当是store
//这里面的方法一般不直接改变数据,而需要通过mutations里面的方法修改
addA_async(context) {
console.log(context);
clearTimeout(context.rootState.timer);
context.rootState.timer = setTimeout(() => {
console.log(111);
context.commit("addA");
}, 1000);
},
addB_async(context) {
setTimeout(() => {
context.commit("addB");
}, 1000);
},
addAN_async(context, payload) {
setTimeout(() => {
context.commit("addAN", payload);
}, 1000);
},
},
后续使用的时候,其实就两种方法,第一种就是通过$store,写起来比较繁琐,我们先试试这种
<div class="home">
<div>
<h3>state</h3>
<p>a:{{ $store.state.a }}</p>
<p>b:{{ $store.state.b }}</p>
</div>
<div>
<h3>getters</h3>
<p>doubleA:{{ $store.getters.doubleA }}</p>
<p>doubleA:{{ $store.getters.doubleB }}</p>
<p>doubleBoth:{{ $store.getters.doubleBoth }}</p>
</div>
<div>
<h3>mutations</h3>
<p>
<button @click="$store.commit('addA')">a++</button>
<button @click="$store.commit('addAN',10)">a+10</button>
</p>
<p>
<button @click="$store.commit('addB')">b++</button>
</p>
</div>
<div>
<h3>actions</h3>
<p>
<button @click="$store.dispatch('addA_Async')">a++</button>
<button @click="$store.dispatch('addAN_Async',10)">a+10</button>
</p>
<p>
<button @click="$store.dispatch('addB_Async')">b++</button>
</p>
<p>
<button @click="$store.dispatch('addBoth_Async')">a++,b++</button>
</p>
<p>
<button @click="$store.dispatch('test')">test</button>
</p>
</div>
</div>
我们可以观察到,调用同步方法需要用commit,而异步方法则是dispatch,后续的函数名和参数也要对应写入
而第二种方法,就是利用官方提供的封装函数,直接将变量和store内的数据关联起来,有点像是解构赋值
<script>
// @ is an alias to /src
import { mapState,mapGetters,mapMutations,mapActions } from "vuex";
export default {
name: 'HomeView',
components: {
},
computed:{
...mapState(["a","b"]),
...mapGetters(["doubleA","doubleB","doubleBoth"]),
},
methods:{
...mapMutations(["addA","addAN","addB"]),
...mapActions(["addA_async","addAN_async","addB_async","addBoth_Async"]),
}
}
</script>
然后使用起来就简单很多
<div>
<h1>state类似于vue-data</h1>
<p>a:{{ a }}</p>
<p>b:{{ b }}</p>
</div>
<div>
<h1>getters类似于vue-computed</h1>
<p>多倍a:{{ doubleA }}</p>
<p>多倍b:{{ doubleB }}</p>
<p>doubleBoth:{{ doubleBoth }}</p>
</div>
<div>
<h1>mutations类似于vue-methods(sync only)</h1>
<button @click="addA">a++</button>
<button @click="addB">b++</button>
<button @click="addAN(10)">a+10</button>
</div>
<div>
<h1>actions类似于vue-methods(async only)</h1>
<h2>不可直接改数据,必须用mutations的方法</h2>
<button @click="addA_async">a++</button>
<button @click="addB_async">b++</button>
<button @click="addAN_async(10)">a+10</button>
</div>
</div>
总结:
-
state类似vue中的data; -
getters类似vue中的计算属性-> 依赖于state
// 函数中的第一参数: state -> 当前store实例中的state对象
// 函数中的第二参数: getters -> 当前store实例中的getters对象
mutations类似vue中的methods-> 依赖于state (mutayions中的方法只能是同步的)
// 函数中的第一参数: state -> 当前store实例中的state对象
// 函数中的第二参数: payload(载荷) 方法被调用时可以接收一个实际参数被形参接收
actions类似vue中的methods-> 依赖于state (actions中的方法只能是异步的)
// 函数中的第一参数: context -> 和store实例有相同属性和方法的新对象 {state,getters,commit,dispatch}
// 函数中的第二参数: payload(载荷) actions方法被调用时可以接收一个实际参数被形参接收
//actions里面的函数想要修改数据,必须要调用mutations里面的方法