前言
vuex是一种专为Vue.js应用程序开发的状态管理模式,挂载在全局中,具有响应式特性
vuex的实现原理主要包括以下几个方面:
下面是一个简单的代码示例,用于说明vuex的实现原理:
// vuex.js
let Vue // 保存Vue构造函数,插件中要使用
class Store {
constructor(options) {
// 保存选项
this.$options = options
// 定义响应式的state
this._vm = new Vue({
data: {
$$state: options.state // 加两个$,Vue不做代理
},
computed: options.getters // 将getters定义为计算属性
})
// 定义commit和dispatch方法
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
// 定义wrappedGetters
this.wrappedGetters = {}
// 实现getters,按照getters的定义挂载到store实例
const computed = {}
Object.keys(this.$options.getters).forEach(key => {
// 获取用户定义的getter
const fn = this.$options.getters[key]
// 转换为computed可以使用无参数形式
computed[key] = () => {
return fn(this.state, this.getters)
}
// 为wrappedGetters定义只读属性
Object.defineProperty(this.wrappedGetters, key, {
get: () => this._vm[key]
})
})
// 实现mutations
this.mutations = {}
Object.keys(this.$options.mutations).forEach(key => {
this.mutations[key] = payload => {
this.$options.mutationskey
}
})
// 实现actions
this.actions = {}
Object.keys(this.$options.actions).forEach(key => {
this.actions[key] = payload => {
this.$options.actionskey
}
})
}
// 存取器,state只读
get state() {
return this._vm._data.$$state
}
set state(v) {
console.error('不能直接修改state,请使用replaceState')
}
// 存取器,getters只读
get getters() {
return this.wrappedGetters
}
// commit,执行mutation
commit(type, payload) {
// 获取type对应的mutation
const fn = this.mutations[type]
if (!fn) {
// 未定义的mutation
console.error(`mutation ${type} 不存在`)
return
}
// 传入state和负载
fn(payload)
}
// dispatch,执行action
dispatch(type, payload) {
// 获取type对应的action
const fn = this.actions[type]
if (!fn) {
// 未定义的action
console.error(`action ${type} 不存在`)
return
}
// 传入当前Store实例和负载
return fn(payload)
}
}
// install方法
function install(_Vue) {
Vue = _Vue // 保存Vue构造函数
// 混入
Vue.mixin({
beforeCreate() {
// 此时,上下文已经是组件实例了
// 如果this是根实例,则它的$options里面会有store实例
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
// 以后就能在组件中拿到 $store
}
}
})
}
// 导出对象
export default { Store, install }
然后在app.js文件中引入使用
// 引入Vue和Vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 使用Vuex插件
Vue.use(Vuex)
// 创建一个store实例
const store = new Vuex.Store({
// 定义state
state: {
count: 0
},
// 定义getters
getters: {
doubleCount: state => state.count * 2
},
// 定义mutations
mutations: {
increment(state, payload) {
state.count += payload
}
},
// 定义actions
actions: {
incrementAsync(context, payload) {
setTimeout(() => {
context.commit('increment', payload)
}, 1000)
}
}
})
// 在组件中使用store
new Vue({
el: '#app',
store,
...
})