vuex
vuex 集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以可预测的形式发生变化
应用vuex
(1) 导入vuex
vue add vuex
(2) 外围概念
state: 状态数据
mutations: 批改状态的函数
action: 异步操作
(3) 状态store -- 保留利用状态
export default new Vuex.store({ state: { counter: 0 }})
(4) mutation -- 状态变更
export default new Vuex.store({ state: { counter: 0 }, mutations: { add(state){ state.counter++ } }})
(5) getters -- 从state中派生出的状态,相似计算属性
export default new Vuex.store({ state: { counter: 0 }, mutations: { add(state){ state.counter++ } }, getters: { doubleCounter(state) { return state.counter * 2 } }})
(6) actions -- 增加业务逻辑
export default new Vuex.store({ state: { counter: 0 }, mutations: { add(state){ state.counter++ } }, actions: { add({commit}){ setTimeout(()=>{ commit('add'); },1000) } }, getters: { doubleCounter(state) { return state.counter * 2 } }})
测试代码
<p @click="$store.commit('add')">counter: {{$store.state.counter}}</p><p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p> <p>double:{{$store.getters.doubleCounter}}</p>
vuex原理剖析
任务分析
实现插件
(1) 实现store类维持一个响应式的store 实现commit 实现dispatch getters
(2) 挂载$store
- 初始化 Store申明, install实现
let Vue;class Store{ constructor(options) { // data响应式解决 this._vm = new Vue({ data: { $$state: options.state } }) } get state(){ return this._vm_data.$$state }}function install(_Vue) { Vue = _Vue; Vue.mixin({ beforeCreated(){ if (this.$options.store) { Vue.prototype.$store = this.$options.store } } })}export default {Store, install}
实现commit 依据用户传入的type获取并执行对应的mutations
class Store{ constructor(options) { // data响应式解决 this._vm = new Vue({ data: { $$state: options.state } }) // 保留用户配置的mutations选项 this._mutations = options._mutations || {}; this._actions = options._actions || {}; } get state(){ return this._vm_data.$$state } commit (type) { // 获取type指定的mutation const entry = this._mutations[type]; if (!entry) { console.log('unknow mutation') return } // 传递state给mutation entry(this.state); } dispatch (type) { // 获取type指定的mutation const entry = this._mutations[type]; if (!entry) { console.log('unknow mutation') return } // 传递state给mutation entry(this.state); }}
实现dispatch 依据用户传入的type获取并执行对应的actions
class Store{ constructor(options) { // data响应式解决 this._vm = new Vue({ data: { $$state: options.state } }) // 保留用户配置的mutations选项 this._mutations = options._mutations || {}; this._actions = options._actions || {}; // 须要异步解决上下文 this.dispatch = this.dispatch.bind(this); } get state(){ return this._vm_data.$$state } dispatch (type) { // 获取type指定的action const entry = this._actions[type]; if (!entry) { console.log('unknow action') return } // 传递state给action entry(this); }}
实现getters
class Store{ constructor(options) { // data响应式解决 this._vm = new Vue({ data: { $$state: options.state } }) // 保留用户配置的mutations选项 this._mutations = options._mutations || {}; this._actions = options._actions || {}; // 须要异步解决上下文 this.dispatch = this.dispatch.bind(this); this.getters = {}; Object.keys(options.getters).forEach(getterName => { Object.defineProperty(this.getter, getterName, { get:()=>{ return options.getters[getterName](this.state) } }) }) } get state(){ return this._vm_data.$$state }}
残缺代码
// 1. 插件: 挂载$store// 2. 实现Storelet Vueclass Store { constructor(options) { // data响应式解决 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); // 实现getters this.getters = {}; Object.keys(options.getters).forEach(getterName => { Object.defineProperty(this.getters, getterName, { get: () => { return options.getters[getterName](this.state) } }) }) } get state(){ return this._vm._data.$$state } commit(type, payload) { const entry = this._mutations[type]; if (!type) { console.log('unknow muyations type') } entry(this.state, payload) } dispatch(type, payload) { const entry = this._actions[type]; if (!type) { console.log('unknow action type') } entry(this, payload) }}function install (_Vue) { Vue = _Vue; Vue.mixin({ beforeCreate() { if (this.$options.store) { Vue.prototype.$store = this.$options.store; } }, })}export default {Store, install};