你不知道action與mutation怎麼被調用的?趕忙回去看啊Vuex源碼學習(七)action和mutation如何被調用的(調用篇))vue
上兩個小節已經講述了commit與dispatch如何調用mutation與action的,可是action中有幾個參數感受涉及到了一些咱們遺漏(故意不講)的點。ajax
在installModule的時候 給每一個模塊綁定了一個屬性context。 經過makeLocalContext函數建立的,在註冊action、mutation和getters都有使用。這個context是什麼呢?vuex
咱們按照類型分析bash
// 查看全名,若是沒有全名 多是根模塊或者沒有設置命名空間
const noNamespace = namespace === '';
// 若是沒有全名 就使用全局(store)上的disptach
// 有全名的話 構建一個新的dispatch
// 這個新的dispatch仍然接收三個參數(與store上的dispatch同樣)
//
dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
//unifyObjectStyle 對額外傳入的_options沒有任何處理 只是肯定一下位置
const args = unifyObjectStyle(_type, _payload, _options)
// options 值沒有發生變化
const { payload, options } = args
let { type } = args
// 在disptach的時候是否指定選擇root(根)
// 若是options設置爲{root : true} 那麼就會跳過下面
if (!options || !options.root) {
// 拼接真正的名字
type = namespace + type
if (process.env.NODE_ENV !== 'production' && !store._actions[type]) {
console.error(`[vuex] unknown local action type: ${args.type}, global type: ${type}`)
return
}
}
// 調用(補全名字後)的action
return store.dispatch(type, payload)
},
複製代碼
這段代碼咱們能夠看出來,local對象(也就是模塊的context屬性)中的dispacth會在未指定使用根模塊名字時,會把dispatch調用的名字強行加上這個模塊的全名,用這個dispatch調用的action都會變成你這個模塊下的action函數
通俗的講 咱們想要調用A模塊(有命名空間的某個action B)須要作的是post
this.$store.dispatch('A模塊的全名/B的名字');
複製代碼
在A模塊的action中想要使用dispatch來作一些事情。學習
actions.js
export const ajaxGetUserName = ({dispatch})=>{
// 這個時候用dispatch調用本身模塊內的其他的action不須要加上全名
dispatch('ajaxGetUserAge');
// 想要變成和根模塊同樣的dispatch 須要加上一個options註明{root : true}
// 這個時候dispatch就會變成全局的 不會主動幫你拼接全名了
}
export const ajaxGetUserAge = () => {
// do something
}
複製代碼
同理local對象下的commit也是作了一樣的事情,ui
兩個方法說完了,下面該講兩個屬性了this
這兩個屬性就是咱們的getters與state,可是這是咱們local對象中,也就是局部模塊下的getters與state。getters與state如何建立的 getters 首先判斷全名是否是爲空,爲空就返回store對象的getters,有的話就建立局部getters。與其說是建立不如說是代理lua
makeLocalGetters源碼
function makeLocalGetters (store, namespace) {
// 設計思想
//其實咱們並不須要建立一套getters,
// 只要咱們在local中經過getters來獲取一些局部模塊的值的時候,
// 能夠被代理到真正存放這些getters的地方。
// 建立代理對象
const gettersProxy = {}
// 找到切割點
const splitPos = namespace.length
Object.keys(store.getters).forEach(type => {
// skip if the target getter is not match this namespace
// 得去getters裏面找一下有沒有這個namespace爲前綴的getter。
// 沒有就找不到了
if (type.slice(0, splitPos) !== namespace) return
// extract local getter type
// 拿到模塊內註冊的那個局部的getter名字
// 全名是set/getName
// localType就是getName
const localType = type.slice(splitPos)
// Add a port to the getters proxy.
// Define as getter property because
// we do not want to evaluate the getters in this time.
// 完成代理任務,
// 在查詢局部名字是被代理到對應的store.getters中的(全名)getter
Object.defineProperty(gettersProxy, localType, {
get: () => store.getters[type],
enumerable: true
})
})
//返回代理對象
return gettersProxy
}
複製代碼
建立局部的getters就是一個代理的過程,在使用模塊內使用(沒有加上命名空間的)getters的名字,會被代理到,store實例上那個真正的(全名的)getters。
state 這個相對來講就簡單不少了
context是如何被建立的你們已經比較瞭解了。context的做用是什麼? (local就是contenxt)以前說過註冊mutation、action、getters都用到了local。用他們幹什麼?一一介紹
1. 註冊mutation
2. 註冊dispatch
可是隻給了dispatch傳入了store的getters與state(雖然有了這倆你想要什麼放在vuex的數據都能獲得),並無給store的dispatch與mutation。
這就說名dispatch能夠查看store中的全部數據,你放在vuex裏面的數據我均可以看,可是你想改不使用特殊手段,很差意思只能改本身模塊的。
3. 註冊getters
在註冊中咱們能夠看到,vuex對這個改變數據的權限控制的很嚴格,可是查看數據控制的很鬆,改只能改本身模塊的,查你願意怎麼看都OK。
{root:true}
)來解開局部模塊的限制。這個章節結束,咱們全部和模塊有關的內容就已經完結了。 對於模塊作一個小的總結。
因此模塊爲Vuex提供了不少方便,方便的去獲取數據、修改數據。那麼Vuex真正的數據倉庫在哪裏?數據都存儲在哪裏? 咱們下一章見