vuex的使用

89 阅读3分钟

基础

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
        });