阅读 44

VUE之vuex状态管理器

Vuex 是一个状态管理器,用来管理Vue的所有组件状态。

作用

当项目中组件较多,结构复杂时,我们可以把它们的公共状态提取出来,放在vuex里面统一管理。

使用

一个基本的vuex结构,store为存储的公共数据,mutations为修改数据的方法,actions是异步操作

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex) 

//store是存储数据,以及提供数据访问接口
export default new Vuex.Store({
  state: { //存储数据
    num: 1
  },
  getters: { //计算属性,对数据进行处理运算
    getMyNum: function(state){
      return state.num
    }
  },
  mutations: { // 改变数据
    add(state, payload) {
      state.num += payload;
    }
  },
  actions: { //异步,{commit, dispatch}是一个解构
     add2({commit, dispatch}, payload) {
      setTimeout(() => {
        //actions自己不更新,要调用mutations的方法更新
        commit('add', payload);
      }, 1000)
    }
  }
})
复制代码

在组件中访问vuex里的数据使用this.$store

<p>{{this.$store.state.num}}</p>
<p>{{this.$store.getters.getMyNum}}</p>
复制代码

在组件中调用vuex的方法

this.$store.commit("add", 1); //(方法名,参数)
this.$store.dispatch("add2", 2); //异步调用
复制代码

自己实现vuex

//自定义vuex
let Vue;

//数据存储
class Store { 
    constructor(options) { 
        this.vm = new Vue({ //放到vue里实现数据的监听
            data: {
                state: options.state //传入的数据
            }
        })

        //getters
        let getters = options.getters; //获取传入的getters
        this.getters = {}; //定义当前的getters
        // 遍历传入的getters
        Object.keys(getters).forEach(getterName => { //getterName是定义的计算属性
            //动态定义属性,定义到this.getters当前的getters
            Object.defineProperty(this.getters, getterName, {
                get: () => { //定义遍历的属性,并且返回执行传入的方法,传入的参数
                    return getters[getterName](this.state)
                }
            })
        })

        //修改数据
        let actions = options.actions;
        this.actions = {};
        Object.keys(actions).forEach(actionName => {
            //给this.actions添加函数,执行传入的actions的函数
            this.actions[actionName] = (payload) => {
                actions[actionName](this, payload);
            }
        })

        let mutations = options.mutations;
        this.mutations = {};
        Object.keys(mutations).forEach(mutationName => {
            this.mutations[mutationName] = (payload) => {
                mutations[mutationName](this.state, payload);
            }
        })

    }

    get state() { //增加访问的方法
        return this.vm.state;
    }

    dispatch(type, payload) {
        this.actions[type](payload)
    }

    commit = (type, payload) => { //type是传入的参数名字,payload是参数
        //找到mutations里的参数名字并执行
        this.mutations[type](payload);
    }
}

//需要在所有的组件中添加$store对象,让它们可以使用this.$store.commit()
const install = (v) => {
    Vue = v;
    Vue.mixin({ //混合,给所有子组件添加方法
        beforeCreate() { //组件初始化之前
            console.log(this.$options.name) //组件名字
            if(this.$options && this.$options.store) {
                //有store一定是根组件
                this.$store = this.$options.store
            }else{
                //子组件,将父组件的store赋给它
                this.$store = this.$parent && this.$parent.$store;
            }
        }
    })
}

//导出插件
export default {install, Store}
复制代码