一、Vuex 是如何注入到 Vue 中的
beforeCreate 执行时将 $store 挂载到 vue 的原型链上。
let Vue;
function install(vm,storeName='$store'){
Vue = vm;
Vue.mixin({beforeCreate() {if(this.$options.store){
// 将 $store 挂载到 Vue 的原型上
Vue.prototype[storeName] = this.$options.store;
}
}
})
}
二、Vuex 如何实现状态响应式核心
本质上是采用了 Vue 的数据响应原理
// 注册 state
const store = new vuex.Store({
state:{inputText:''},
......
});
//new vuex.Store 的时候将 state 映射到 Vue 实例中的 data 上
class Store{constructor(options={}){
this.state = new Vue({data:options.state})
}
.....
}
三、getter
getter 的作用是对 state 进行计算处理,类似 vue 的 computed 对属性进行计算一样。getter 的原理是利用 Object.defineProperty 劫持属性的 getter 将计算后的结果保存在 vuex 的 getter 中。
registerGetter(getters){this.getters = {}
let vm = this.state;
for (const key in getters) {if (getters.hasOwnProperty(key)) {
Object.defineProperty(this.getters,key,{get(){
// 调用 vuex 参数中 getter 的函数,并将结果缓存在 getter 里面
return getters[key](vm);
}
})
}
}
}
四、Mutations 如何更新状态
1、注册 mutations 函数
const store = new vuex.Store({
state:{inputText:''},
mutations:{
/** 这里的 state 实际上是一个 vue 的实例 */
updateInputText(state,payload){state.inputText = payload;}
}
});
2、更改状态必须触发 commit 函数,commit 函数调用 mutaions 里面的函数,并将 vue 实例和需要更改的数据传递给 mutations 函数。
commit(m_name,payload){const fn = this.mutations[m_name];
fn(this.state,payload);
}
3、为什么 mutations 必须是异步的?
如果是异步的会导致 devtool 调试困难,很难追踪到状态的改变。
五、action
1、action 类似 mutation,不同的在于:action 提交的是 mutation;action 可以是异步,但 mutation 只能是同步。
2、注册 actions
const store = new vuex.Store({
state:{inputText:''},
mutations:{updateInputText(state,payload){state.inputText = payload;}
},
actions:{text({commit}){
// 模拟一个异步操作
setTimeout(() => {commit('updateInputText')
}, 1000);
}
}
});
3、分发 action,必须触发 dispatch 方法。dispatch 函数会将 commit/state/getters 传递给 action 函数。
dispatch(a_name,arg){
// 源码在此处使用 promise 进行异步处理
const fn = this.actions[a_name];
fn({
commit:this.commit,
state:this.state,
getters:this.getters
},arg);
}
4、为什么需要 action 进行异步管理?
场景:假如有两个异步操作 A 和 B,它们都会操作同一个 mutation,并且 B 需要在 A 提交 mutation 后才提交。
当有这样复杂的操作时就需要使用 action 来处理异步问题了。
actions: {
// ...
actionB ({dispatch, commit}) {return dispatch('actionA').then(() => {commit('someOtherMutation')
})
}
}
六、常用的插件
1、vuex-persistedstate
使用浏览器的本地存储(local storage)对状态(state)进行持久化。这意味着刷新页面或关闭标签页都不会删除你的数据。
2、vuex-shared-mutations
可在不同的标签页之间同步状态。它通过 mutation 将状态储存到本地存储来实现。选项卡、窗口中的内容更新时触发储存事件,重新调用 mutation,从而保持状态同步。
3、vuex-i18n
允许你轻松地用多种语言存储内容。让你的应用切换语言时更容易。
4、vuex-loading
有助于你管理应用中的多个加载状态。这个插件适用于状态变化频繁且复杂的实时应用程序。
5、vuex-cache
可以缓存 Vuex 的 action。例如,如果你从服务器检索数据,这个插件将在第一次调用该 action 时缓存结果,然后在之后的 dispatch 中,直接返回缓存的值。必要时清除缓存也很简单。
参考文章
https://www.cnblogs.com/haishen/p/11315669.html