实现vuex源码,手写
Vuex 是专门为 Vue.js 应用程序开发的状态管理模式 + 库,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
第一步:定义初始化Store类
创建文件夹store/vuex.js
1.定义 Store 类:
创建一个名为 Store 的类,它接受一个 options 对象作为参数。
在 options 对象中,包含 state(应用的状态)、mutations(同步更改状态的方法)、actions(异步操作或包含任意异步操作的方法)、以及 getters(从 state 中派生出一些状态的方法)。
let Vue;
class Store{
constructor(options) {
}
}
1
2
3
4
5
6
2.初始化 Vue 实例:
在 Store 类的构造函数中,使用 new Vue({ data: { $$state: options.state } }) 创建一个 Vue 实例,用于响应式地存储状态。这里使用 $$state 作为属性的名称是为了避免与 Vue 实例自身的 state 属性冲突,但这不是必须的,只是一个命名约定。
let Vue;
class Store{
constructor(options) {
this._vm = new Vue({
data:{
$$state:options.state } }) } } 1 2 3 4 5 6 7 8 9 10 3.存储 mutations 和 actions: 将 options.mutations 和 options.actions 分别存储在 this._mutations 和 this._actions 中。 let Vue; class Store{ constructor(options) { this._vm = new Vue({ data:{ $$state:options.state
}
})
this._mutations = options.mutations
this._actions = options.actions
}
}
1
2
3
4
5
6
7
8
9
10
11
12
4.绑定 commit 和 dispatch 方法:
使用 Function.prototype.bind 方法将 commit 和 dispatch 方法绑定到 Store 实例上,以确保在回调函数中 this 指向正确。
let Vue;
class Store{
constructor(options) {
this._vm = new Vue({
data:{
$$state:options.state } }) this._mutations = options.mutations this._actions = options.actions this.commit = this.commit.bind(this) this.dispatch = this.dispatch.bind(this) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 5.初始化 getters: 创建一个空对象 this.getters 用于存储 getter 方法。 如果 options.getters 存在,则调用 this.handleGetters(options.getters) 方法来初始化 getters。 let Vue; class Store{ constructor(options) { this._vm = new Vue({ data:{ $$state:options.state
}
})
this._mutations = options.mutations
this._actions = options.actions
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
this.getters = {}
options.getters && this.hanleGetters(options.getters)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第二步:实现 handleGetters 方法和其他 Store 方法
1.实现 handleGetters 方法:
在 handleGetters 方法中,遍历 getters 对象的键。
使用 Object.defineProperty 在 this.getters 对象上定义每个 getter 属性,其 get 方法返回 getterskey 的结果。
let Vue;
class Store{
constructor(options) {
this._vm = new Vue({
data:{
$$state:options.state } }) this._mutations = options.mutations this._actions = options.actions this.commit = this.commit.bind(this) this.dispatch = this.dispatch.bind(this) this.getters = {} options.getters && this.hanleGetters(options.getters) } handleGetters(getters){ Object.key(getters).map((key)=>{ Object.defineProperty(this.getters,key, get: () => getters[key](this.state) }) }) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2.实现 state 的 getter 和 setter: 使用 get state() 方法来访问 Vue 实例中存储的状态。 使用 set state(v) 方法来防止直接修改状态(虽然在这里,setter 只是打印了一个错误消息)。 let Vue; class Store{ constructor(options) { this._vm = new Vue({ data:{ $$state:options.state
}
})
this._mutations = options.mutations
this._actions = options.actions
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
this.getters = {}
options.getters && this.hanleGetters(options.getters)
}
handleGetters(getters){
Object.key(getters).map((key)=>{
Object.defineProperty(this.getters,key,
get: () => getterskey
})
})
}
//get set
get state(){
return this._vm.data.$$state } set state(v) { console.error("please provide"); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3.实现 commit 方法: commit 方法用于触发 mutations,它接受一个 type(mutation 的类型)和一个可选的 payload(传递给 mutation 的数据)。 根据 type 从 this._mutations 中找到对应的 mutation 方法,并调用它,传入 this.state 和 payload。 let Vue; class Store{ constructor(options) { this._vm = new Vue({ data:{ $$state:options.state
}
})
this._mutations = options.mutations
this._actions = options.actions
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
this.getters = {}
options.getters && this.hanleGetters(options.getters)
}
handleGetters(getters){
Object.key(getters).map((key)=>{
Object.defineProperty(this.getters,key,
get: () => getterskey
})
})
}
//get set
get state(){
return this._vm.data.$$state
}
set state(v) {
console.error("please provide");
}
//commit
commit(type,value){
const entry = this._mutations[type]
if(!entry){
console.error("please provide");
}
entry(this.state,value)
}
}