前言~~不喜欢手写原理的程序员不是好的程序员
根据vuex官网的使用,下面来实现以下基础的vuex中心化数据响应式原理
1.首先来看一下 store注册

store注册使用了vue的插件机制,use方法会调用插件的install方法

用过store的我们可以得知,在vue中每个实例的每个方法都可以通过this.$store 调用数据仓库,
这样我们就可以得出,我们的vuex插件是有install方法,主要实现了store的全局混入,我们这里利用一些vue的mixin全局混入,beforeCreate生命周期一开始就对vue组件实例注入到this.$store中
/**
* store.js - store 注册
*/
let Vue
// vue 插件必须要这个 install 函数
export function install(_Vue) {
// 拿到 Vue 的构造器,存起来
Vue = _Vue
// 通过 mixin 注入到每一个vue实例 👉 https://cn.vuejs.org/v2/guide/mixins.html
Vue.mixin({ beforeCreate: vuexInit })
function vuexInit () {
const options = this.$options
// 这样就可以通过 this.$store 访问到 Vuex 实例,拿到 store 了
if (options.store) {
this.$store = typeof options.store === 'function'
? options.store()
: options.store
} else if (options.parent && options.parent.$store) {
this.$store = options.parent.$store
}
}
}
2. 实现vuex的响应式功能
说到响应式功能,我们是否可以利用vue的响应式原理呢
export class Store {
constructor(options = {}) {
resetStoreVM(this, options.state)
}
get state () {
return this._vm._data.$$state
}
}
function resetStoreVM(store, state) {
// 因为 vue 实例的 data 是响应式的,正好利用这一点,就可以实现 state 的响应式
store._vm = new Vue({
data: {
$$state: state
}
})
}
3. vuex的衍生数据,getters
class Store{
constructor(options={}){
this.resetStoreVm(options.state)
const { mutations,actions,getters } = options
this.options = options
// 我们用 getters 来收集衍生数据 computed
this.getters = {}
// 简单处理一下,衍生不就是计算一下嘛,传人 state
for(let key in getters){
Object.defineProperty(this.getters,key,{
get:()=>getters[key](this.state)
})
}
}
get state(){
return this._vm._data.$$state
}
resetStoreVm(state){
this._vm = new Vue({
data:{
$$state:state
}
})
}
}
4.实现Actions/Mutations
class Store{
constructor(options={}){
this.resetStoreVm(options.state)
const { mutations,actions,getters } = options
this.options = options
// 我们用 getters 来收集衍生数据 computed
this.getters = {}
// 简单处理一下,衍生不就是计算一下嘛,传人 state
for(let key in getters){
Object.defineProperty(this.getters,key,{
get:()=>getters[key](this.state)
})
}
// 定义的行为,分别对应异步和同步行为处理
this.mutations = {}
this.actions = {}
for(let key in mutations){
this.mutations[key] = (payload)=>{
// 最终执行的就是 this._vm_data.$$state.xxx = xxx 这种操作
mutations[key](this.state,payload)
}
}
for(let key in actions){
this.actions[key] = (payload)=>{
// action 专注于处理异步,这里传入 this,这样就可以在异步里面通过 commit 触发 mutation 同步数据变化了
actions[key](this,payload)
}
}
}
get state(){
return this._vm._data.$$state
}
resetStoreVm(state){
this._vm = new Vue({
data:{
$$state:state
}
})
}
// 触发 mutation 的方式固定是 commit
commit(name,payload){
return this.mutations[name](payload)
}
// 触发 action 的方式固定是 dispatch
dispatch(name,payload){
return this.actions[name](payload)
}
}
359

被折叠的 条评论
为什么被折叠?



