前端日報--學習vuex(一)
在vue爛在滿大街的情況下,面試中問到vue
核心外掛實現原理是很平常的事情。
抱著學習的態度,我們來學習下vuex
的原始碼。
在學習之前,我們希望得到什麼答案呢?
在很長的時間,我們都在討論vuex
的關鍵的幾個可以被用於單向流動的固定節點:dispatch->acition(commit)->mutation->state
。所以本坑希望我們讀完原始碼後,我們知道為什麼vuex一定要遵循這幾個節點單向的流動,狀態是怎麼銜接過去的?
。
第二個問題就是,
vuex
它如何實現響應式的狀態變化?
。
第三個問題就是,
我們是否能夠準確口述vuex
大致實現和管理策略呢?
從頭開始
vue
的入口檔案是src\index.js
,開啟看看:
和其他外掛一樣,在專案通過use(vuex)
來呼叫install
方法來安裝vuex
的,除此之外還提供其他方法,比如常常在各個模組使用的map類函式。
import { Store, install } from './store' import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' export default { Store, install, version: '__VERSION__', mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers }
我們先看看install
方法,當執行Vue.use(vuex)
便開始啟動install
。為了防止多次呼叫install方法引發的多次安裝,程式碼中通過賦值比較的方式來實現。看似簡單卻解決了這個問題。這裡有個小點:如果多次Vue.use(vuex)
,封裝的use程式碼裡會先檢查Vue
的_installedPlugins
陣列是否有該外掛,如果有則直接返回,並不會進入外掛install
裡。
export function install (_Vue) { if (Vue && _Vue === Vue) { if (process.env.NODE_ENV !== 'production') { console.error( '[vuex] already installed. Vue.use(Vuex) should be called only once.' ) } return } Vue = _Vue applyMixin(Vue) }
可以看到程式碼根據版本來使用不同的方式來applyMixin
,如果是2.0
版本則把vuexInit
初始化的方法混入beforeCreate鉤子裡,如果不是,則合併到_init
原型方法裡頭。vuexInit
方法能夠讓例項中各個層級能夠訪問到和根節點一樣的store
.自此install過程就完成了。
export default function (Vue) { const version = Number(Vue.version.split('.')[0]) if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }) } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. const _init = Vue.prototype._init Vue.prototype._init = function (options = {}) { options.init = options.init ? [vuexInit].concat(options.init) : vuexInit _init.call(this, options) } } /** * Vuex init hook, injected into each instances init hooks list. */ function vuexInit () { const options = this.$options // store injection 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 } } }
下一節,store的建構函式說起。