vuex插件主要用于统一管理vue项目中的数据流动状态。详细介绍见官网:vuex.vuejs.org/vue
实现简易版的vuex的步骤以下:vuex
直接上源码,注释比较清楚。bash
// rvuex.js let Vue; class Store{ constructor(options){ // 保存全部mutations this._mutations = options.mutations; // 保存全部actions this._actions = options.actions; // 处理全部getters // 定义computed选项 const { computed } = this.dealGetters(options.getters); // 响应化处理state,当state值发生变化时,触发渲染函数从新渲染视图 // 能够经过实例化Vue,在data中设置使属性变为响应式 this._vm = new Vue({ data: { $$state: options.state }, computed }); // 绑定commit,dispatch的上下文为当前store实例 this.commit = this.commit.bind(this); this.dispatch = this.dispatch.bind(this); } // store中getters定义方式{ doubleCounter(state){return state.counter * 2} } // store中读取getters里的值:{{$store.getters.doubleCounter}} dealGetters(getters = {}){ let computed = {}; let store = this; store.getters = {}; // 遍历用户定义的getters Object.keys(getters).forEach(key => { // 获取用户定义的getter const getter = getters[key]; // 好比 doubleCounter(state){return state.counter * 2} // 将getter转换为computed形式,computed里的函数是无参数的 // computed计算属性,其实是调用getters里的方法 computed[key]= function(){ return getter(store.state); }; // 为getters定义只读属性 // 当读取getters里面的属性值时,实际上是读取的vue实例里的computed计算属性 Object.defineProperty(store.getters, key, { get: () => store._vm[key] }); }); return { computed }; } // 存取器 get state(){ return this._vm._data.$$state; } set state(value){ console.error('不能直接设置state的值'); } // commit mutation来触发state的更新 // $store.commit('add', 1) // params: // type: mutation的类型 // payload: 载荷,多余的参数 commit(type, payload){ const entry = this._mutations[type]; if(entry) { entry(this.state, payload); } } dispatch(type, payload){ const entry = this._actions[type]; if(entry){ entry(this, payload); } } } function install(_Vue){ Vue = _Vue; // $store的全局挂载 Vue.mixin({ beforeCreate() { // 只有根组件(入口文件)才会传入store // 而后将this.$options.store挂载到vue原型上,这样vue组件内部能够经过this.$store来访问 if(this.$options.store){ Vue.prototype.$store = this.$options.store; } } }) } // Vuex export default { Store, install } 复制代码
先定义store.jsmarkdown
// store.js import Vue from 'vue' import Vuex from 'rvuex' // 上面rvuex.js文件 Vue.use(Vuex) export default new Vuex.Store({ state: { counter: 0 }, getters:{ doubleCounter(state){ return state.counter * 2 } }, mutations: { add(state){ state.counter ++ } }, actions: { // 参数为执行上下文 add({commit}){ setTimeout(() => { commit('add') }, 1000) } } }) 复制代码
在组件中使用store里的数据。async
// index.vue <template> <div> <p @click="$store.commit('add')">counter: {{$store.state.counter}}</p> <p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p> <p>double counter: {{$store.getters.doubleCounter}}</p> <router-view /> </div> </template> 复制代码
以上内容为网上学习课程的复习总结。函数