简易vuex源码实现
kvuex.js 文件 (实现vuex插件)
// 1、维护状态state // 2、修改状态commit // 3、业务逻辑控制dispatch // 4、状态派发getter // 5、实现state响应式 // 6、插件 // 7、混入 let Vue function install(_Vue, storeName = '$store') { Vue = _Vue // 混入:把store选项指定到Vue原型上 Vue.mixin({ beforeCreate() { // 判断main.js的当期组件选择中,是否有sotre if(this.$options.store){ Vue.prototype[storeName] = this.$options.store } } }) } class Store { // options: { state: {count:0}, mutations:{count(state){}} } constructor(options = {}){ // 利用vue数据响应式 this.state = new Vue({ data: options.state }) // 初始化mutations this.mutations = options.mutations || {} this.actions = options.actions || {} options.getters && this.handleGetters(options.getters) } // 触发mutations,需要实现commit commit = (type, arg) => { // this只想Store实例 const fn = this.mutations[type] // 获取状态变更函数 fn(this.state, arg) } dispatch = (type, arg) => { const fn = this.actions[type] return fn({commit: this.commit, state: this.state}, arg) } // {getters: {score(state){return state.xx}}} handleGetters(getters){ this.getters = {} // store实例上的getters // 定义只读的属性 Object.keys(getters).forEach(key => { Object.defineProperty(this.getters, key, { get: () => { return getters[key](this.state) } }) }) } } export default {Store, install}
kindex.js 文件 相当于store.js文件
import Vue from 'vue' import KVuex from '../kvuex' Vue.use(KVuex) export default new KVuex.Store({ state: { count: 0 }, mutations: { add(state, num = 1) { state.count += num } }, getters: { // 相当于计算属性 score(state) { return 'score:' + state.count } }, actions: { // 处理复杂业务逻辑,类似于controller // 比如ajax请求 asyncAdd({ commit }) { // 参数解构,拿到上下文 setTimeout(() => { commit('add') }, 1000); } } })
测试文件---vue文件
<template>
<div>
<h3>vuex test</h3>
<p>{{$store.state.count}}</p>
<p>{{$store.getters.score}}</p>
<button @click="add">add</button>
<button @click="asyncAdd">asyncAdd</button>
</div>
</template>
<script>
export default {
methods: {
add() {
this.$store.commit('add', 2)
},
asyncAdd(){
this.$store.dispatch('asyncAdd')
}
},
}
</script>

浙公网安备 33010602011771号