介紹
採用集中式儲存管理應用的所有元件的狀態, 就能實現元件間資料共享
實現
邏輯圖
從圖上有兩條線: Vue.use(vuec)
, 與 new Vuec.center(options)
第一條線Vue.use(vuec)
安裝外掛
使用Vue.use(vuec)
時, 會執行vuec
的install
方法,會注入引數Vue
所以vuec
是這樣的,
// index.jsimport {Center, install
} from './center'export default {Center, install
}複製程式碼
Center
物件將例項化成center
(下面再說),我們先看看install
方法
// center.jslet Vue // 全域性變數, 儲存install裡的Vueexport function install (_Vue) {
if (!Vue) {
_Vue.mixin({
beforeCreate: applyMixin // 在beforeCreate鉤子上混入applyMixin函式
})
} Vue = _Vue
}複製程式碼
install
在Vue
原型的beforeCreate
混入applyMixin
函式, 也就是說在生成每個Vue
元件時,在它的生命週期beforeCreate
鉤子上就會執行applyMixin
方法
第二條線 new Vuec.center(options)
例項化Center
物件
先看看使用者傳入的options
, 下面例子
export default new Vuec.Center({
state: {
name: 'liuyang'
}, mutations: {
changeName (state) {
state.name = 'jike'
}
}
})複製程式碼
上面程式碼會生成center
例項, 該例項上應該包括:state
狀態,commit
方法提交變更等
// center.jsexport class Center {
constructor (options= {
}) {
let center = this this.mutations = options.mutations observeState(center, options.state)
} get state () {
// 代理了this.$center.state的最終訪問值 return this._vm.$data.$$state
} commit (_type, _payload) {
this.mutations[_type](this.state, _payload)
}
}function observeState(center, state) {
// 響應式state center._vm = new Vue({
data: {
$$state: state
}
})
}複製程式碼
在執行new Vuec.Center({..
時,就是執行
})Center
的建構函式
-
首先執行
let center = this
, 定義center
儲存當前例項 -
接著執行
this.mutations = options.mutations
, 在例項center
上新增mutations
屬性, 值就是使用者輸入mutations
,按上面例子,
this.mutations
長成這樣this.mutations = {
changeName (state) {
state.name = 'jike'
}
}複製程式碼 -
最後執行
observeState(center, options.state)
, 作用:讓center
例項的state
屬性指向options.state
並且是響應式的
function observeState(center, state) {
// 響應式state center._vm = new Vue({
// 利用Vue的響應系統,將state轉化成響應式 data: {
$$state: state
}
})
}複製程式碼
在center
例項上新增_vm
屬性, 值是一個Vue
例項, 在該Vue
例項的data
下定義了$$state
, 它的值是options.state
使用者輸入的state
;
結合上面的這段程式碼
// center.jsexport class Center {
...省略 get state () {
// 代理了this.$center.state的最終訪問值 return this._vm.$data.$$state
} ...省略
}複製程式碼
所以我們在元件中訪問center.state
其實就是訪問center._vm.$data.$$state
OK, center
就構建好了
建立Vue
元件
使用者輸入
import Vue from 'vue'import App from './App'import router from './router'import center from './center'new Vue({
el: '#app', router, center, // 構建好的center例項 template: '<
App/>
', components: {App
}
})複製程式碼
在beforeCreate
生命週期時會觸發上面混入的applyMixin
函式
// mixins.jsexport default function applyMixin() {
vuecInit.call(this) //
}function vuecInit () {
const options = this.$options // vue的例項化是從外往內, 所以父元件的$center一定是options的center this.$center = options.parent?options.parent.$center: options.center
}複製程式碼
applyMixin
裡會執行vuecInit.call(this)
, 這裡的this
指向當前元件的例項,
接著看vuecInit
, 定義了options
等於使用者輸入選項,因為先建立根元件, 所以根元件this.$center
的值的引用就是我們在new Vue({..center
時傳入的
})center
例項, 下面所有元件都指向它
OK, 你就可以在元件裡使用this.$center
訪問了
commit變更
// center.jsexport class Center {
... 省略 commit (_type, _payload) {
this.mutations[_type](this.state, _payload)
}
}複製程式碼
通常我們變更時: this.$center.commit('changeName', 'jike')
, 這樣的話, this.mutations[_type]
就是對應方法函式, 往該函式裡傳入state
以及payload
,
舉上面的例子
// this.mutations[_type] , _type = 'changeName', payload= 'jike'this.mutations = {
changeName (state, payload) {
state.name = payload
}
}複製程式碼
說明
上面只是一個簡單的狀態管理, 還有很多地方沒有實現: actions
非同步變更,getters
函式,modules
模組分割, 輔助函式mapState..
等
原始碼地址: github