Vuex核心概念
Vuex是集中式存储管理应用的所有组件的状态,并以相应的规则保证以可预测的方式发生变化
安装插件:vue add vuex
组成部分:
- state状态、数据
- mutations更改状态的函数
- actions异步操作
- store包含以上概念的容器
状态-state
state保存应用状态,store.js
export default new Vuex.Store({
state: {counter:0}
})
状态变更-mutations
mutations用于修改状态,store.js
export default new Vuex.Store({
mutations:{
add(state){
state.counter++
}
}
})
派生状态-getters
从state派生出新状态,类似于计算属性
export default new Vuex.Store({
getters:{
doubleCounter(state){
return state.counter*2
}
}
})
动作-actions
添加业务逻辑,类似于controller
export default new Vuex.Store({
actions:{
add({commit}){
setTimeout(()=>{
commit('add')
},1000)
}
}
})
Vuex原理解析
问题分析:
实现插件:
一是实现Store类
有以下几点:
1、维持一个响应式状态state
2、实现commit()
3、实现dispatch()
4、实现类似于计算属性getters
二是挂载$store
/**
* 1、声明一个插件
* 2、实现一个Store
* 实现响应式state属性
* 实现两个方法commit()/dispatch()
*/
let Vue;
class Store {
constructor(options) {
// 1、保存选项
this._mutations = options.mutations || {};
this._actions = options.actions || {};
// 2、做响应式状态的state属性
// Vue.util.defineReactive(this, 'state', {})
this._vm = new Vue({
data: {
$$state: options.state
},
computed: {
getters() {
return options.getters;
}
}
});
// 上下文对象绑定this
this.commit = this.commit.bind(this);
this.dispatch = this.dispatch.bind(this);
// 实现getters
// 1.动态设置getters属性
// 2.响应式
// 3.能否利用上vue的computed计算属性缓存
this.initGetters = this.initGetters.bind(this);
}
// 给用户暴露接口
get state() {
// console.log(this._vm);
// $data不是响应式,_data是响应式
return this._vm._data.$$state;
}
set state(v) {
console.error("please use replaceState to reset");
}
// getters
get getters() {
return this.initGetters();
}
set getters(v) {
console.error("please use replaceGetters to reset");
}
// 执行getters里的函数,返回一个对象集合
initGetters() {
const newGetters = {};
for (const key in this._vm.getters) {
newGetters[key] = this._vm.getters[key](this.state);
}
return newGetters;
}
// store.commit(type, payload)
commit(type, payload) {
// 获取mutations
const entry = this._mutations[type];
if (!entry) console.error("unknown mutations type");
entry(this.state, payload);
}
// store.dispatch(type, payload)
dispatch(type, payload) {
// 获取actions
const entry = this._actions[type];
if (!entry) console.error("unknown actions type");
// {commit, dispatch, state, getters}
entry(this, payload);
}
}
function install(_Vue) {
Vue = _Vue;
// 挂载$store
Vue.mixin({
beforeCreate() {
// 这里this指向组件实例,new Vue({store(参数)})
if (this.$options.store) {
// 给每个组件实例暴露store实例
Vue.prototype.$store = this.options.store;
}
}
});
}
// 导出对象相当于Vuex
export default { Store, install };