欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue中復(fù)用vuex.store對(duì)象的定義

 更新時(shí)間:2022年09月08日 09:26:34   作者:左直拳  
這篇文章主要介紹了vue中復(fù)用vuex.store對(duì)象的定義,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

復(fù)用vuex.store對(duì)象的定義

我有幾個(gè)組件,都需要用到vuex.store,而且這幾個(gè)組件結(jié)構(gòu)極其類(lèi)似,就在想,能不能復(fù)用store的對(duì)象定義?因?yàn)槊總€(gè)組件都定義一遍,繁瑣,且沒(méi)必要。

主要是用到克隆組件。具體代碼如下:

1. 共用的store定義

/src/store/common.js

export default {
? namespaced: true,
? state: {
? ? v: "hello store", // for test
? ? items: [],
? },
? getters: {
? ? v: (state) => state.v,
? ? items: (state) => {
? ? ? return state.items;
? ? },
? },
? mutations: {
? ? // 同步操作
? ? setV(state, val) {
? ? ? state.v = val;
? ? },
? ? setItems(state, val) {
? ? ? state.items = val;
? ? },
? },
? actions: {
? ? keepItems: ({ commit }, val) => {
? ? ? commit("setItems", val);
? ? },
? },
};

2. 組件1

/src/store/component1.js

import cloneDeep from "lodash/cloneDeep";
import common from "./common";
const category = cloneDeep(common);
export default component1;

3. 組件2

/src/store/component2.js

import cloneDeep from "lodash/cloneDeep";
import common from "./common";
const category = cloneDeep(common);
export default component2;

vuex中的store

1. Vuex是什么

在了解Store之前,我們先來(lái)看看Vuex是個(gè)什么東西。Vuex本質(zhì)上就是一個(gè)Vue.js的插件,是用于對(duì)復(fù)雜應(yīng)用進(jìn)行狀態(tài)管理用的,打印Vuex以后輸出:

{
?
? Store: function Store(){},
?
? mapActions: function(){}, // 對(duì)應(yīng)Actions的結(jié)果集
?
? mapGetters: function(){}, // 對(duì)應(yīng)Getters的結(jié)果集
?
? mapMutations: function(){}, // 對(duì)應(yīng)Mutations的結(jié)果集
?
? mapState: function(){}, // 對(duì)應(yīng)State的結(jié)果集
?
? install: function install(){},
?
? installed: true
?
}

Vuex和單純的全局對(duì)象有以下兩點(diǎn)不同:

  • Vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的。當(dāng)Vue 組件從 Store 中讀取狀態(tài)的時(shí)候,若 Store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新。
  • 不能直接改變 Store 中的狀態(tài)。改變Store 中的狀態(tài)的唯一途徑就是顯式地提交 mutation。

2. Store

每一個(gè)Vuex應(yīng)用的核心就是Store(倉(cāng)庫(kù)),我們可以說(shuō)Store是一個(gè)容器,Store里面的狀態(tài)與單純的全局變量是不一樣的,無(wú)法直接改變Store中的狀態(tài)。想要改變Store中的狀態(tài),只有一個(gè)辦法,顯式地提交mutation。

3. 一個(gè)完整的Store結(jié)構(gòu)

const store = new Vuex.Store({
? state: {
? ? // 存放狀態(tài)
? },
? getters: {
? ? // state的計(jì)算屬性
? },
? mutations: {
? ? // 更改state中狀態(tài)的邏輯,同步操作
? },
? actions: {
? ? // 提交mutation,異步操作
? },
? // 如果將store分成一個(gè)個(gè)的模塊的話,則需要用到modules。
? ?//然后在每一個(gè)module中寫(xiě)state, getters, mutations, actions等。
? modules: {
? ? a: moduleA,
? ? b: moduleB,
? ? // ...
? }
});

4. 狀態(tài)管理的幾個(gè)核心概念

1. state

state是狀態(tài)數(shù)據(jù),可以通過(guò)this.$store.state來(lái)直接獲取狀態(tài),也可以利用vuex提供的mapState輔助函數(shù)將state映射到計(jì)算屬性(computed)中去。用data接收的值不能及時(shí)響應(yīng)更新,用computed就可以:

export default {
? data () {
? ? return {
? ? ? dataCount: this.$store.state.count //用data接收
? ? }
? },
? computed:{
? ? count(){
? ? ? return this.$store.state.count //用computed接收
? ? }
? }
}

mapState 輔助函數(shù):

mapState是state的語(yǔ)法糖,當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)時(shí)候,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余。為了解決這個(gè)問(wèn)題,我們可以使用 mapState 輔助函數(shù)幫助我們生成計(jì)算屬性,讓你少按幾次鍵:

// 在單獨(dú)構(gòu)建的版本中輔助函數(shù)為 Vuex.mapState
import { mapState } from 'vuex'
?
export default {
? // ...
? computed: mapState({
? ? // 箭頭函數(shù)可使代碼更簡(jiǎn)練
? ? count: state => state.count,
?
? ? // 傳字符串參數(shù) 'count' 等同于 `state => state.count`
? ? countAlias: 'count',
?
? ? // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù)
? ? countPlusLocalState (state) {
? ? ? return state.count + this.localCount
? ? }
? })
}

當(dāng)映射的計(jì)算屬性的名稱(chēng)與 state 的子節(jié)點(diǎn)名稱(chēng)相同時(shí),我們也可以給 mapState 傳一個(gè)字符串?dāng)?shù)組。

computed: mapState([
? // 映射 this.count 為 store.state.count
? 'count'
])

     

2. getter

getters本質(zhì)上是用來(lái)對(duì)狀態(tài)進(jìn)行加工處理。Getters與State的關(guān)系,就像Vue.js的computed與data的關(guān)系。getter 的返回值會(huì)根據(jù)它的依賴(lài)被緩存起來(lái),且只有當(dāng)它的依賴(lài)值發(fā)生了改變才會(huì)被重新計(jì)算??梢酝ㄟ^(guò)this.$store.getters.valueName對(duì)派生出來(lái)的狀態(tài)進(jìn)行訪問(wèn)?;蛘咧苯邮褂幂o助函數(shù)mapGetters將其映射到本地計(jì)算屬性中去。

mapGetters 輔助函數(shù):

mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性:

import { mapGetters } from 'vuex'
export default {
? // ...
? computed: {
? // 使用對(duì)象展開(kāi)運(yùn)算符將 getter 混入 computed 對(duì)象中
? ? ...mapGetters([
? ? ? 'doneTodosCount',
? ? ? 'anotherGetter',
? ? ? // ...
? ? ])
? }
}

mapGetters實(shí)際上是一個(gè)方法Vuex對(duì)象上的一個(gè)方法,這從本文開(kāi)頭打印的那個(gè)Vuex對(duì)象的內(nèi)容可以看出來(lái)。…這個(gè)符號(hào)是ES2015的一個(gè)新的語(yǔ)法糖,即將mapGetters處理后的內(nèi)容展開(kāi)后填入。

如果你想將一個(gè) getter 屬性另取一個(gè)名字,使用對(duì)象形式:

mapGetters({
? // 映射 `this.doneCount` 為 `store.getters.doneTodosCount`
? doneCount: 'doneTodosCount'
})

       

3. mutation

mutations的中文意思是“變化”,利用它可以更改狀態(tài)。事實(shí)上,更改 Vuex 的 store 中的狀態(tài)的唯一方法就是提交 (commit)mutation。不過(guò),mutation觸發(fā)狀態(tài)改變的方式有一點(diǎn)特別,所謂commit一個(gè)mutation,實(shí)際是像觸發(fā)一個(gè)事件一樣,傳入一個(gè)mutation的類(lèi)型以及攜帶一些數(shù)據(jù)(稱(chēng)作payload,載荷)。

mutations: { ? //放置mutations方法
?? ?increment(state, payload) {
?? ??? ?//在這里改變state中的數(shù)據(jù)
?? ??? ?state.count = payload.number;
?? ?}
},

那commit一個(gè)mutation在代碼層面怎么表示呢?

this.$store.commit('increment', {
? amount: 10
})
//或者這樣
this.$store.commit({
? type: 'increment',
? amount: 10
})

除了這種使用 this.$store.commit('xxx') 提交 mutation的方式之外,還有一種方式,即使用 mapMutations 輔助函數(shù)將組件中的 methods 映射為 this.$store.commit。例如:

import { mapMutations } from 'vuex'
?
export default {
? // ...
? methods: {
? ? ...mapMutations([
? ? ? 'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`
?
? ? ? // `mapMutations` 也支持載荷:
? ? ? 'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
? ? ]),
? ? ...mapMutations({
? ? ? add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
? ? })
? }
}

經(jīng)過(guò)這樣的映射之后,就可以通過(guò)調(diào)用方法的方式來(lái)觸發(fā)其對(duì)應(yīng)的(所映射到的)mutation commit了,比如,上例中調(diào)用add()方法,就相當(dāng)于執(zhí)行了this.$store.commit('increment')了。

考慮到觸發(fā)的mutation的type必須與mutations里聲明的mutation名稱(chēng)一致,比較好的方式是把這些mutation都集中到一個(gè)文件(如mutation-types)中以常量的形式定義,在其它地方再將這個(gè)文件引入,便于管理。而且這樣做還有一個(gè)好處,就是整個(gè)應(yīng)用中一共有哪些mutation type可以一目了然。就像下面這樣:

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
?
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
?
const store = new Vuex.Store({
? state: { ... },
? mutations: {
? ? // 我們可以使用 ES2015 風(fēng)格的計(jì)算屬性命名功能來(lái)使用一個(gè)常量作為函數(shù)名
? ? [SOME_MUTATION] (state) {
? ? ? // mutate state
? ? }
? }
})

         

4. action

action可以提交mutation,在action中可以執(zhí)行store.commit,而且action中可以有任何的異步操作:

const store = new Vuex.Store({
? state: {
? ? count: 0
? },
? mutations: {
? ? increment (state) {
? ? ? state.count++
? ? }
? },
? actions: {
? ? increment (context) {
? ? ? context.commit('increment')
? ? }
? }
})

或者用ES2015的參數(shù)解構(gòu),可以簡(jiǎn)寫(xiě)成:

actions: {
? ? increment ({commit}) {
? ? ? ?? ?commit('increment')
? ? }
}

和mutation類(lèi)似,我們像上面這樣生命action的處理函數(shù)。它接收的第一個(gè)參數(shù)是一個(gè)與 store 實(shí)例具有相同方法和屬性的 context 對(duì)象,因此你可以調(diào)用 context.commit 提交一個(gè) mutation,或者通過(guò) context.state 和 context.getters 來(lái)獲取 state 和 getters。

不過(guò),mutation處理函數(shù)中所做的事情是改變state,而action處理函數(shù)中所做的事情則是commit mutation。

怎么觸發(fā)action呢?按照Vuex的叫法,這叫分發(fā)(dispatch),我們反正知道它實(shí)際上是觸發(fā)的意思就行了。具體的觸發(fā)方法是this.$store.dispatch(actionType, payload)。所傳的兩個(gè)參數(shù)一個(gè)是要觸發(fā)的action的類(lèi)型,一個(gè)是所攜帶的數(shù)據(jù)(payload),類(lèi)似于上文所講的commit mutation時(shí)所傳的那兩個(gè)參數(shù)。具體如下:

// 以載荷形式分發(fā)
this.$store.dispatch('incrementAsync', {
? amount: 10
})

或 

// 以對(duì)象形式分發(fā)
this.$store.dispatch({
? type: 'incrementAsync',
? amount: 10
})

還有一種方法是使用 mapActions 輔助函數(shù)將組件的 methods 映射為 this.$store.dispatch 調(diào)用。如下:

import { mapActions } from 'vuex'
?
export default {
? // ...
? methods: {
? ? ...mapActions([
? ? ? 'increment', // 將 `this.increment()` 映射為 `this.$store.dispatch('increment')`
?
? ? ? // `mapActions` 也支持載荷:
? ? ? 'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.dispatch('incrementBy', amount)`
? ? ]),
? ? ...mapActions({
? ? ? add: 'increment' // 將 `this.add()` 映射為 `this.$store.dispatch('increment')`
? ? })
? }
}

另外,還需要知道, this.$store.dispatch 可以處理被觸發(fā)的 action 的處理函數(shù)返回的 Promise,并且 this.$store.dispatch 仍舊返回 Promise。

再來(lái)看一些組合性的異步操作:

actions: {
? actionA ({ commit }) {
? ? return new Promise((resolve, reject) => {
? ? ? setTimeout(() => {
? ? ? ? commit('someMutation')
? ? ? ? resolve()
? ? ? }, 1000)
? ? })
? }
}

現(xiàn)在你可以:

$this.store.dispatch('actionA').then(() => {
? // ...
})

在另外一個(gè) action 中也可以:

actions: {
? // ...
? actionB ({ dispatch, commit }) {
? ? return dispatch('actionA').then(() => {
? ? ? commit('someOtherMutation')
? ? })
? }
}

最后,如果我們利用 async / await 這個(gè) JavaScript 即將到來(lái)的新特性,我們可以像這樣組合 action:

// 假設(shè) getData() 和 getOtherData() 返回的是 Promise
actions: {
? async actionA ({ commit }) {
? ? commit('gotData', await getData())
? },
? async actionB ({ dispatch, commit }) {
? ? await dispatch('actionA') // 等待 actionA 完成
? ? commit('gotOtherData', await getOtherData())
? }
}

接著來(lái)看一個(gè)更加實(shí)際的購(gòu)物車(chē)示例,涉及到調(diào)用異步 API 和分發(fā)多重 mutation:

actions: {
? checkout ({ commit, state }, products) {
? ? // 把當(dāng)前購(gòu)物車(chē)的物品備份起來(lái)
? ? const savedCartItems = [...state.cart.added]
? ? // 發(fā)出結(jié)賬請(qǐng)求,然后樂(lè)觀地清空購(gòu)物車(chē)
? ? commit(types.CHECKOUT_REQUEST)
? ? // 購(gòu)物 API 接受一個(gè)成功回調(diào)和一個(gè)失敗回調(diào)
? ? shop.buyProducts(
? ? ? products,
? ? ? // 成功操作
? ? ? () => commit(types.CHECKOUT_SUCCESS),
? ? ? // 失敗操作
? ? ? () => commit(types.CHECKOUT_FAILURE, savedCartItems)
? ? )
? }
}

         

5. module

module是對(duì)于store的一種切割。由于Vuex使用的是單一狀態(tài)樹(shù),這樣整個(gè)應(yīng)用的所有狀態(tài)都會(huì)集中到一個(gè)比較大的對(duì)象上面,那么,當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對(duì)象就很可能變得相當(dāng)臃腫!它解決了當(dāng)state中很臃腫的時(shí)候,module可以將store分割成模塊,每個(gè)模塊中擁有自己的state、mutation、action和getter。就像下面這樣:

const moduleA = {
? state: { ... },
? mutations: { ... },
? actions: { ... },
? getters: { ... }
}
?
const moduleB = {
? state: { ... },
? mutations: { ... },
? actions: { ... }
}
?
const store = new Vuex.Store({
? modules: {
? ? a: moduleA,
? ? b: moduleB
? }
})
?
store.state.a // -> moduleA 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)

模塊的局部狀態(tài)

對(duì)于每個(gè)模塊內(nèi)部的 mutation 和 getter,接收的第一個(gè)參數(shù)就是模塊的局部狀態(tài)對(duì)象。

const moduleA = {
? state: { count: 0 },
? mutations: {
? ? increment (state) {
? ? ? // 這里的 `state` 對(duì)象是模塊的局部狀態(tài)
? ? ? state.count++
? ? }
? },
?
? getters: {
? ? doubleCount (state) {
? ? ? return state.count * 2
? ? }
? }
}

同樣,對(duì)于模塊內(nèi)部的 action,局部狀態(tài)通過(guò) context.state 暴露出來(lái),根節(jié)點(diǎn)狀態(tài)則為 context.rootState:

const moduleA = {
? // ...
? actions: {
? ? incrementIfOddOnRootSum ({ state, commit, rootState }) {
? ? ? if ((state.count + rootState.count) % 2 === 1) {
? ? ? ? commit('increment')
? ? ? }
? ? }
? }
}

對(duì)于模塊內(nèi)部的 getter,根節(jié)點(diǎn)狀態(tài)會(huì)作為第三個(gè)參數(shù)暴露出來(lái):

const moduleA = {
? // ...
? getters: {
? ? sumWithRootCount (state, getters, rootState) {
? ? ? return state.count + rootState.count
? ? }
? }
}

命名空間

默認(rèn)情況下,模塊內(nèi)部的 action、mutation 和 getter 是注冊(cè)在全局命名空間的——這樣使得多個(gè)模塊能夠?qū)ν?mutation 或 action 作出響應(yīng)。

如果希望你的模塊具有更高的封裝度和復(fù)用性,你可以通過(guò)添加 namespaced: true 的方式使其成為命名空間模塊。當(dāng)模塊被注冊(cè)后,它的所有 getter、action 及 mutation 都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào)整命名。

例如:

const store = new Vuex.Store({
? modules: {
? ? account: {
? ? ? namespaced: true,
?
? ? ? // 模塊內(nèi)容(module assets)
? ? ? state: { ... }, // 模塊內(nèi)的狀態(tài)已經(jīng)是嵌套的了,使用 `namespaced` 屬性不會(huì)對(duì)其產(chǎn)生影響
? ? ? getters: {
? ? ? ? isAdmin () { ... } // -> getters['account/isAdmin']
? ? ? },
? ? ? actions: {
? ? ? ? login () { ... } // -> dispatch('account/login')
? ? ? },
? ? ? mutations: {
? ? ? ? login () { ... } // -> commit('account/login')
? ? ? },
?
? ? ? // 嵌套模塊
? ? ? modules: {
? ? ? ? // 繼承父模塊的命名空間
? ? ? ? myPage: {
? ? ? ? ? state: { ... },
? ? ? ? ? getters: {
? ? ? ? ? ? profile () { ... } // -> getters['account/profile']
? ? ? ? ? }
? ? ? ? },
?
? ? ? ? // 進(jìn)一步嵌套命名空間
? ? ? ? posts: {
? ? ? ? ? namespaced: true,
?
? ? ? ? ? state: { ... },
? ? ? ? ? getters: {
? ? ? ? ? ? popular () { ... } // -> getters['account/posts/popular']
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
})

啟用了命名空間的 getter 和 action 會(huì)收到局部化的 getter,dispatch 和 commit。

在命名空間模塊內(nèi)訪問(wèn)全局內(nèi)容(Global Assets)

如果你希望使用全局 state 和 getter,rootState 和 rootGetter 會(huì)作為第三和第四參數(shù)傳入 getter,也會(huì)通過(guò) context 對(duì)象的屬性傳入 action。

若需要在全局命名空間內(nèi)分發(fā) action 或提交 mutation,將 { root: true } 作為第三參數(shù)傳給 dispatch 或 commit即可。

modules: {
? foo: {
? ? namespaced: true,
?
? ? getters: {
? ? ? // 在這個(gè)模塊的 getter 中,`getters` 被局部化了
? ? ? // 你可以使用 getter 的第四個(gè)參數(shù)來(lái)調(diào)用 `rootGetters`
? ? ? someGetter (state, getters, rootState, rootGetters) {
? ? ? ? getters.someOtherGetter // -> 'foo/someOtherGetter'
? ? ? ? rootGetters.someOtherGetter // -> 'someOtherGetter'
? ? ? },
? ? ? someOtherGetter: state => { ... }
? ? },
?
? ? actions: {
? ? ? // 在這個(gè)模塊中, dispatch 和 commit 也被局部化了
? ? ? // 他們可以接受 `root` 屬性以訪問(wèn)根 dispatch 或 commit
? ? ? someAction ({ dispatch, commit, getters, rootGetters }) {
? ? ? ? getters.someGetter // -> 'foo/someGetter'
? ? ? ? rootGetters.someGetter // -> 'someGetter'
?
? ? ? ? dispatch('someOtherAction') // -> 'foo/someOtherAction'
? ? ? ? dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
?
? ? ? ? commit('someMutation') // -> 'foo/someMutation'
? ? ? ? commit('someMutation', null, { root: true }) // -> 'someMutation'
? ? ? },
? ? ? someOtherAction (ctx, payload) { ... }
? ? }
? }
}

帶命名空間的綁定函數(shù)

當(dāng)使用 mapState, mapGetters, mapActions 和 mapMutations 這些函數(shù)來(lái)綁定命名空間模塊時(shí),寫(xiě)起來(lái)可能比較繁瑣:

computed: {
? ...mapState({
? ? a: state => state.some.nested.module.a,
? ? b: state => state.some.nested.module.b
? })
},
methods: {
? ...mapActions([
? ? 'some/nested/module/foo',
? ? 'some/nested/module/bar'
? ])
}

對(duì)于這種情況,你可以將模塊的空間名稱(chēng)字符串作為第一個(gè)參數(shù)傳遞給上述函數(shù),這樣所有綁定都會(huì)自動(dòng)將該模塊作為上下文。于是上面的例子可以簡(jiǎn)化為:

computed: {
? ...mapState('some/nested/module', {
? ? a: state => state.a,
? ? b: state => state.b
? })
},
methods: {
? ...mapActions('some/nested/module', [
? ? 'foo',
? ? 'bar'
? ])
}

而且,你可以通過(guò)使用 createNamespacedHelpers 創(chuàng)建基于某個(gè)命名空間輔助函數(shù)。它返回一個(gè)對(duì)象,對(duì)象里有新的綁定在給定命名空間值上的組件綁定輔助函數(shù):

import { createNamespacedHelpers } from 'vuex'
?
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
?
export default {
? computed: {
? ? // 在 `some/nested/module` 中查找
? ? ...mapState({
? ? ? a: state => state.a,
? ? ? b: state => state.b
? ? })
? },
? methods: {
? ? // 在 `some/nested/module` 中查找
? ? ...mapActions([
? ? ? 'foo',
? ? ? 'bar'
? ? ])
? }
}

給插件開(kāi)發(fā)者的注意事項(xiàng)

如果你開(kāi)發(fā)的插件(Plugin)提供了模塊并允許用戶(hù)將其添加到 Vuex store,可能需要考慮模塊的空間名稱(chēng)問(wèn)題。對(duì)于這種情況,你可以通過(guò)插件的參數(shù)對(duì)象來(lái)允許用戶(hù)指定空間名稱(chēng):

// 通過(guò)插件的參數(shù)對(duì)象得到空間名稱(chēng)
// 然后返回 Vuex 插件函數(shù)
export function createPlugin (options = {}) {
? return function (store) {
? ? // 把空間名字添加到插件模塊的類(lèi)型(type)中去
? ? const namespace = options.namespace || ''
? ? store.dispatch(namespace + 'pluginAction')
? }
}

模塊動(dòng)態(tài)注冊(cè)

在 store 創(chuàng)建之后,你可以使用 store.registerModule 方法注冊(cè)模塊:

// 注冊(cè)模塊 `myModule`
store.registerModule('myModule', {
? // ...
})
// 注冊(cè)嵌套模塊 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
? // ...
})

之后就可以通過(guò) store.state.myModule 和 store.state.nested.myModule 訪問(wèn)模塊的狀態(tài)。

模塊動(dòng)態(tài)注冊(cè)功能使得其他 Vue 插件可以通過(guò)在 store 中附加新模塊的方式來(lái)使用 Vuex 管理狀態(tài)。例如,vuex-router-sync 插件就是通過(guò)動(dòng)態(tài)注冊(cè)模塊將 vue-router 和 vuex 結(jié)合在一起,實(shí)現(xiàn)應(yīng)用的路由狀態(tài)管理。

你也可以使用 store.unregisterModule(moduleName) 來(lái)動(dòng)態(tài)卸載模塊。注意,你不能使用此方法卸載靜態(tài)模塊(即創(chuàng)建 store 時(shí)聲明的模塊)。

模塊重用

有時(shí)我們可能需要?jiǎng)?chuàng)建一個(gè)模塊的多個(gè)實(shí)例,例如:

(1)創(chuàng)建多個(gè) store,他們公用同一個(gè)模塊

(2)在一個(gè) store 中多次注冊(cè)同一個(gè)模塊

如果我們使用一個(gè)純對(duì)象來(lái)聲明模塊的狀態(tài),那么這個(gè)狀態(tài)對(duì)象會(huì)通過(guò)引用被共享,導(dǎo)致?tīng)顟B(tài)對(duì)象被修改時(shí) store 或模塊間數(shù)據(jù)互相污染的問(wèn)題。

實(shí)際上這和 Vue 組件內(nèi)的 data 是同樣的問(wèn)題。因此解決辦法也是相同的——使用一個(gè)函數(shù)來(lái)聲明模塊狀態(tài)(僅 2.3.0+ 支持):

const MyReusableModule = {
? state () {
? ? return {
? ? ? foo: 'bar'
? ? }
? },
? // mutation, action 和 getter 等等...
}

5. store與$store的區(qū)別

$store 是掛載在 Vue 實(shí)例上的(即Vue.prototype),組件也是一個(gè)Vue實(shí)例,在組件中可使用 this 訪問(wèn)原型上的屬性。template 中可直接通過(guò) {{ $store.state.userName }} 訪問(wèn),等價(jià)于 script 中的 this.$store.state.userName。

至于 {{ store.state.userName }},script 中的 data 需聲明過(guò) store 才可訪問(wèn)。

總之,有以下要注意的:

(1)在功能上:

  • state保存的是數(shù)據(jù)
  • getters是對(duì)state進(jìn)行二次加工
  • action的處理函數(shù)的功能最終是commit mutation
  • mutation處理函數(shù)的功能最終是改變state

(2)在流程上:

vue component—-dispatch—->actions—-commit—->mutations—-mutate—->state—-render—->vue component。從而形成閉環(huán)。

(3)輔助方法的映射上:

mapGetters、mapState 都是用在computed聲明里面;

mapActions、mapMutations則都是用在methods聲明里面。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論