基础
vuex的代码是:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter:1
},
mutations: {
add(state){
return state.counter++;
}
},
actions: {
add({commit}){
commit("add");
}
},
modules: {
}
})
如下是vuex的初级的一些使用:
<p @click="$store.commit('add')">$store.commit点击+1:{{$store.state.counter}}</p>
<p @click="$store.dispatch('add')">$store.dispatch点击+1:{{$store.state.counter}}</p>
dispath通过改变mutations来改变值。dispath只要提交就可以,值实际上是在mutations中改变的。
vuex插件的实现
通过上述简单的案例,我们可以进行一个实现。
把$store挂载到原型上。实现第一步。
state里边的值可以是响应式的值,只要改变,则会进行重新的渲染。
自己写的MVuex.
vuex的state值的显示
如下代码:
let Vue;
class Store{
constructor(o){
this.state=new Vue({
data(){
return {
state:o.state
}
}
});
}
}
function install(_Vue){
//这个是插件的加载往往是第一步的操作,而我们这个功能是需要这个Vue的,从这里传入是比较合适的。
Vue=_Vue;
//全局混入,判断当前对象的$options是否有store来判断是否是根组件。
//如果是根组件则进行Vue原型绑定store。
Vue.mixin({
beforeCreate(){
if(this.$options.store){
Vue.prototype.$store=this.$options.store;
}
}
});
}
//index.js 需要使用插件的加载和Store类对象的创建,所以至少返回一个install方法和Sore类
export default{
Store,
install
}
store方法的响应式实现
//这里的sate是Vue的一个变量,用于做参数传递给方法里边的。不同之处可以用作响应式
this.state=new Vue({
data:o.state //直接绑定在vue对象上
});
之后所用的值都用this.state。
commit方法的实现
这个实现方法真的太帅了。
commit是执行了mutations里边的方法。而commit是store的一个方法。
具体代码和注释如下:
//获取所有的mutations里的方法
this._mutations=o.mutations;
然后在该类里边定义commit方法:
//实现commit方法
commit(type,payload){
//type是方法的意思,通过传递不同的方法名执行不同的方法
//方法都是写在mutations对象里边传递进来的。
//获取当前传递的方法
const entry=this._mutations[type];
if(entry){//如果方法存在,则执行方法
entry(this.state,payload);
}
}
dispatch的实现
这个方法的实现也真的太棒了。
根据disatch的使用,就是它的参数可以解析出 commit 或者 dispatch说明明传递的是Store本身。
注意:因为在dispatch里边有一个commit()的操作的执行,但是这个操作的this并不是Store而是undefined(严格模式下),所以里边的this.xxxx操作就会无法使用。
所以需要在Store的构造器里边进行this的绑定:
//this乱像的问题,在actions中commit()这个操作的this不是Store,
//所以需要绑定this给this.commit方法和this.dispatch方法。
//绑定后,不管是谁调用this都是Store
this.commit=this.commit.bind(this);
this.dispatch=this.dispatch.bind(this);
dispatch实现的代码如下:
//实现commit方法
commit(type,payload){
//type是方法的意思,通过传递不同的方法名执行不同的方法
//方法都是写在mutations对象里边传递进来的。
//获取当前传递的方法
const entry=this._mutations[type];
if(entry){//如果方法存在,则执行方法
entry(this.state,payload);
}
}
作业:getters的实现
因为看懂前面的了,所以学这个是比较简单的。
但是实际上,这个比之前几个好像多难一些。
已经实现了,解决的方法是自己编写一个computed模式的对象。
难点有两个:一个是this的指向问题,因为执行的方法是在另一个vue里边,所以需要给另一个vue提供条件。 第二个难点是:新的new 里边data的数据问题。
具体代码:
this._getters=o.getters;
const getterKeys=Object.keys(this._getters);
//定义一个空的computed模板
let computedGetters={
}
getterKeys.forEach(item=>{
computedGetters[item]=function(){
let newMethod=this.data_getters[item];
return newMethod(this.state);
}
});
//getter方法的实现
this.getters=new Vue({
data:{
state:o.state,
data_getters:o.getters
},
computed:computedGetters
});