个人笔记-vuex
個(gè)人筆記-vuex
最近想要沉淀下自己的知識(shí)體系,以前光看不記,當(dāng)時(shí)記得,過(guò)段時(shí)間記憶就模糊了,好腦子不如爛筆頭,古人誠(chéng)不欺我,所以現(xiàn)在決定給用自己的語(yǔ)言方式來(lái)給自己記個(gè)筆記。
vuex
vuex 有什么好講的呢,現(xiàn)在的組件通訊有太多方法了,但這種作為vue全家桶里的一員,使用還是蠻廣泛的,關(guān)于這方面的資料也很多,但我這個(gè)筆記是以自己的理解方式用大白話來(lái)講的,有不對(duì)的還講指正。(文章里的代碼摘自vuex的中文官網(wǎng)vuex.vuejs.org/zh/)
為什么要用vuex
我們知道,vue是基于組件化的,各管各的,如果這個(gè)時(shí)候,兄弟組件之間的需要共用某個(gè)數(shù)據(jù),該怎么通訊呢,方法有很多,比如父子級(jí)別的可以通過(guò)props和$emit來(lái)解決,爺孫級(jí)別的可以通過(guò)$attrs和$listeners來(lái)解決,如果各自相互獨(dú)立的組件還可能通過(guò)中央總線事件來(lái)通訊,基本上這三種算是常見(jiàn)的了,當(dāng)然,也有人說(shuō),可以做個(gè)全局的變量,然后大家都去拿,在大型項(xiàng)目開(kāi)發(fā)中,這個(gè)變量你存了某個(gè)值,然后又被另一個(gè)人改了,你根本不知道是找哪個(gè)人哪行代碼改了,這個(gè)時(shí)候就需要我們進(jìn)行一個(gè)約定,一個(gè)特定的地方,保存我們共同的東西,通過(guò)約定的方法去更改,以便我們能定位到是誰(shuí)改了,傳了什么東西進(jìn)來(lái),又方便我們進(jìn)行追蹤。vuex還有一個(gè)好處,他里面存的是當(dāng)前的狀態(tài),這就意味著,這里的發(fā)生了變化,能響應(yīng)到對(duì)應(yīng)的組件調(diào)用處。
共同的地方-Store
“store”基本上就是一個(gè)容器,它包含著你的應(yīng)用中大部分的狀態(tài) (state)。
Vue.use(Vuex) // 重點(diǎn) const store = new Vuex.Store({state: {count: 0} }) 復(fù)制代碼store實(shí)例里一定包含一個(gè)state對(duì)象,里就會(huì)存放所有的共有數(shù)據(jù)狀態(tài)。
那么組件里面我要去取到這個(gè)狀態(tài)該怎么做呢,首先要注入
const app = new Vue({el: '#app',// 把 store 對(duì)象提供給 “store” 選項(xiàng),這可以把 store 的實(shí)例注入所有的子組件store,components: { Counter },template: `<div class="app"><counter></counter></div>` }) 復(fù)制代碼在根組件里注入,這樣所屬組件就能通過(guò)this.$store.state訪問(wèn)到store實(shí)例里的state對(duì)象了,其實(shí)這種方法在vue里很常見(jiàn),包括路由啊之類的,都是通過(guò)在根組件注入,所屬組件調(diào)用api的方式來(lái)取值的。
Getter
Getter有什么用呢?之前我們不是可以直接通過(guò)this.$store.state訪問(wèn)到實(shí)例里的state對(duì)象了嗎,那還要這個(gè)有什么用呢,在我看來(lái),Getter有三個(gè)作用
- 可以對(duì)this.$store.state里的某個(gè)屬性做計(jì)算,比如排序啊,過(guò)濾之類的
- 可以直接通過(guò)方法訪問(wèn),對(duì)state里的數(shù)據(jù)進(jìn)行篩選,比如store.getters.fun(id)
- 進(jìn)行映射,這就要用到mapGetters這個(gè)輔助函數(shù):
mapGetters
import { mapGetters } from 'vuex'export default {// ...computed: {// 使用對(duì)象展開(kāi)運(yùn)算符將 getter 混入 computed 對(duì)象中...mapGetters(['doneTodosCount','anotherGetter',// ...])} } 復(fù)制代碼這樣寫(xiě)有什么好處呢,這其實(shí)是一個(gè)映射,可能不同的理解解釋的不一樣,大家也不用糾結(jié),這樣寫(xiě)了之后可以通過(guò)this.doneTodosCount直接拿到,相當(dāng)于把this.$store.state.doneTodosCount映射成了this.doneTodosCount,這樣大家就再也不用噼里啪啦寫(xiě)一堆重復(fù)的東西了。
Mutation
之前我們提到,我們要約定一個(gè)方法去更新state里數(shù)據(jù)的狀態(tài),這個(gè)約定的方法就是提交 mutation。
const store = new Vuex.Store({...mutations: {increment (state) {// 變更狀態(tài)state.count++}} }) 復(fù)制代碼每一個(gè)mutation都類似一個(gè)事件,increment就是這個(gè)事件的type,你不能直接調(diào)用這個(gè)事件的回調(diào),需要以相應(yīng)的 type 調(diào)用 store.commit 方法:store.commit('increment')
有時(shí)候我們要需要對(duì)傳入的數(shù)據(jù)進(jìn)加以第三方數(shù)據(jù)進(jìn)行運(yùn)算,文檔里叫提交載荷
// ... mutations: {increment (state, n) {state.count += n} } 復(fù)制代碼調(diào)用store.commit('increment', 10)
文檔里說(shuō)載荷應(yīng)該是一個(gè)對(duì)象,在大多數(shù)情況下,載荷應(yīng)該是一個(gè)對(duì)象,這樣可以包含多個(gè)字段并且記錄的 mutation 會(huì)更易讀,這塊表示也蒙。。。
// ... mutations: {increment (state, payload) {state.count += payload.amount} } 復(fù)制代碼還有一種對(duì)象提交模式,我覺(jué)得沒(méi)啥用,跳過(guò)。
mapMutations
同mapGetter,也是映射成this.的寫(xiě)法
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')`})} } 復(fù)制代碼使用常量替代 Mutation 事件類型
這個(gè)看項(xiàng)目吧,大型項(xiàng)目可能需要,各種規(guī)范。
敲個(gè)黑板: mutation 都是同步事務(wù),什么是同步事務(wù)呢,簡(jiǎn)單的來(lái)說(shuō)就是狀態(tài)變更都應(yīng)該在此刻完成,不能有異步的操作,需要加入異步的操作見(jiàn)后面的Action知識(shí)點(diǎn)。
Action
Action 類似于 mutation,不同在于:Action 提交的是 mutation,而不是直接變更狀態(tài)。Action 可以包含任意異步操作。
const store = new Vuex.Store({...mutations: {increment (state) {state.count++}},actions: {/* es6解構(gòu)寫(xiě)法increment ({ commit }) {commit('increment')}*/increment (context) {context.commit('increment')}} }) 復(fù)制代碼這個(gè)context是個(gè)什么東西呢,文檔上面是這么說(shuō)的:與 store 實(shí)例具有相同方法和屬性的 context 對(duì)象,因此你可以調(diào)用 context.commit 提交一個(gè) mutation,或者通過(guò) context.state 和 context.getters 來(lái)獲取 state 和 getters。
Action 通過(guò) store.dispatch 方法觸發(fā):store.dispatch('increment'),同時(shí)Action里支持異步操作,舉個(gè)簡(jiǎn)單的例子
actions: {incrementAsync ({ commit }) {setTimeout(() => {commit('increment')}, 1000)} } 復(fù)制代碼action里的寫(xiě)法基本上和mutationu差不多
// 以載荷形式分發(fā) store.dispatch('incrementAsync', {amount: 10 })// 以對(duì)象形式分發(fā) store.dispatch({type: 'incrementAsync',amount: 10 }) 復(fù)制代碼mapActions
功能同之前的類似
組合 Action
組合Action,我個(gè)人用的不多,但原理要了解一下,Action支持異步,所以在Action里可以寫(xiě)異步的commit,包括Promise,包括多個(gè)commit依賴性的先后觸發(fā)。
Module
大型項(xiàng)目多人會(huì)用到的東西,各自管各自的模塊。每個(gè)模塊都有自己對(duì)應(yīng)的一套完整的store,然后再通過(guò)modules組合到頂層的store里去。
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) 復(fù)制代碼對(duì)于module,我覺(jué)得只需關(guān)注幾個(gè)點(diǎn)就可了:
模塊內(nèi)部的 mutation 和 getter,接收的第一個(gè)參數(shù)是模塊的局部狀態(tài)對(duì)象,而不是頂層的了。
const moduleA = {state: { count: 0 },mutations: {increment (state) {// 這里的 `state` 對(duì)象是模塊的局部狀態(tài)state.count++}},actions: {incrementIfOddOnRootSum ({ state, commit, rootState }) {if ((state.count + rootState.count) % 2 === 1) {commit('increment')}}},getters: {sumWithRootCount (state, getters, rootState) {return state.count + rootState.count}} } 復(fù)制代碼關(guān)于這塊,我覺(jué)得只需關(guān)注幾個(gè)點(diǎn)就Ok了。
現(xiàn)在的state都指局部的狀態(tài)對(duì)象了,頂級(jí)的狀態(tài)為rootState
const moduleA = {// ...getters: {sumWithRootCount (state, getters, rootState) {return state.count + rootState.count}},actions: {incrementIfOddOnRootSum ({ state, commit, rootState }) {if ((state.count + rootState.count) % 2 === 1) {commit('increment')}}} } 復(fù)制代碼參數(shù)和非module一樣,只不過(guò)多了第三個(gè)參數(shù),這個(gè)參數(shù)指向頂級(jí)狀態(tài)對(duì)象。
命名空間
默認(rèn)情況下,模塊內(nèi)部的action ,mutation,getter是注冊(cè)在全局命名空間的–這樣使得多個(gè)模塊能夠?qū)ν籱utation或者action做出響應(yīng);如果希望你的模塊更加自包含或者提高可重用性,你可以通過(guò)添加namespaced:true 的方式使其成為命名空間模塊,當(dāng)模塊被注冊(cè)后,他的所有g(shù)etter,action,mutation都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào)整命名;x
轉(zhuǎn)載于:https://juejin.im/post/5c85cff4f265da2dde0723f2
總結(jié)
- 上一篇: 查看Oracle 版本信息
- 下一篇: vue——走马灯-类轮播图