Vuex狀態(tài)管理模式

Vuex是什么?

Vuex是一個專為Vue.js應用程序開發(fā)的狀態(tài)管理模式
Vuex是全局的狀態(tài)管理

Vuex用來做什么跪帝?

Vuex用于組件之間的傳值,多個組件共享數(shù)據(jù)
Vuex的數(shù)據(jù)是響應式的,當我們在A組件更新了某個狀態(tài)膀估,來到B組件躁倒,B組件會動態(tài)更新

State

State用來存儲狀態(tài)

在組件中獲取Vuex狀態(tài)

由于Vuex的狀態(tài)存儲是響應式的荞怒,從store實例中讀取狀態(tài)最簡單的方法就是在計算屬性中返回某個狀態(tài):

computed: {
  count: () => store.state.count
  // or 將狀態(tài)從根組件“注入”到每一個子組件中 Vue.use(Vuex)
  count: () => this.$store.state.count
},

mapState 獲取方式

import { mapState } form 'vuex'

computed: {
    ...mapState({
        // 1. 基礎用法 store/index.js
        isLogin: (state) => state.isLogin
        // 2. 使用模塊 store/modules/user.js
        isLogin: (state) => state.user.isLogin
    }),
},

Getters

Getters類似計算屬性,只有當它的依賴發(fā)生改時才會重新求值

Getter 接受 state 作為其第一個參數(shù):

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

在組件中使用

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

mapGetters 獲取方式

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
    // 使用對象展開運算符將 getter 混入 computed 對象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
    // 使用Modules store/user.js
    ...mapGetters('user',[
      'increment',
      'incrementBy',
      // ...
    ])
  }
}

Mutations

更改store中狀態(tài)的唯一方法是mutations

mutations第一個參數(shù)是state

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變更狀態(tài)
      state.count++
    }
  }
})

調用方法

store.commit('increment')

你可以向store.commit傳入額外的參數(shù)

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

記住 Mutation 必須是同步函數(shù)

在組件中提交 Mutation

computed: {
  doneTodosCount () {
    return this.$store.commit('increment')
  }
}

mapMutations 方式提交

import { mapMutations  } from 'vuex'

export default {
  // ...
  methods: {
    // 使用對象展開運算符將 getter 混入 computed 對象中
    ...mapMutations([
      'increment',
      'incrementBy',
      // ...
    ])
    // 使用Modules store/user.js
    ...mapMutations('user',[
      'increment',
      'incrementBy',
      // ...
    ])
  }
}

Action

Action 類似于 mutation秧秉,不同在于:

  • Action 提交的是 mutation褐桌,而不是直接變更狀態(tài)。
  • Action 可以包含任意異步操作象迎。

注冊一個簡單的 action:

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

Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象荧嵌,因此你可以調用context.commit提交一個 mutation呛踊,或者通過context.statecontext.getters來獲取 state 和 getters。

實踐中啦撮,我們會經常用到 ES2015 的 參數(shù)解構 (opens new window)來簡化代碼

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

在組件中觸發(fā) Action

methods: {
  increment () {
    this.$store.dispatch('increment')
  }
}

mapActions 方式觸發(fā)

import { mapActions  } from 'vuex'

export default {
  // ...
  methods: {
    // 使用對象展開運算符將 getter 混入 computed 對象中
    ...mapActions([
      'increment',
      'incrementBy',
      // ...
    ])
    // 使用Modules store/user.js
    ...mapActions('user',[
      'increment',
      'incrementBy',
      // ...
    ])
  }
}

組合 Action

有時候需要組合多個action谭网,例如有時候需要在actionB中調用actionA

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

利用 async / await ,我們可以如下組合 action:

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    // ...
  }
}

Modules

當應用變得非常復雜時赃春,store 對象就有可能變得相當臃腫愉择。
modules 將 store 分割成模塊。
每個模塊擁有自己的 state织中、mutation囤热、action、getter闷哆、甚至是嵌套子模塊礁遵。

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    moduleA,
    moduleB
  }
})

項目使用案例

@/store/modules/user.js :

export default {
    namespaced: true,
    state: {
        // 存儲狀態(tài)
        isLogin: false
    },
    mutations: {
        // 修改狀態(tài)
        SET_ISLOGIN(state, val) {
            state.isLogin = val
        }
    },
    actions: {
        // 異步操作
        login({ commit }, query) {
            api.login({
                code: query.code,
                iv: query.iv
            }).then(res => {
                commit('SET_ISLOGIN', true)
            })
        }
    }
}

@/store/index.js :

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'

// 安裝 Vuex
Vue.use(Vuex)

// 創(chuàng)建一個 store
export default new Vuex.Store({
  modules: {
    user,
    // ...
  }
})

@/main.js :

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from '@/store';

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app');
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搏嗡,隨后出現(xiàn)的幾起案子窿春,更是在濱河造成了極大的恐慌,老刑警劉巖采盒,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旧乞,死亡現(xiàn)場離奇詭異,居然都是意外死亡磅氨,警方通過查閱死者的電腦和手機尺栖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦租,“玉大人延赌,你說我怎么就攤上這事〔娉鳎” “怎么了挫以?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窃祝。 經常有香客問我掐松,道長,這世上最難降的妖魔是什么粪小? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任大磺,我火速辦了婚禮,結果婚禮上探膊,老公的妹妹穿的比我還像新娘杠愧。我一直安慰自己,他們只是感情好突想,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布殴蹄。 她就那樣靜靜地躺著究抓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袭灯。 梳的紋絲不亂的頭發(fā)上刺下,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音稽荧,去河邊找鬼橘茉。 笑死,一個胖子當著我的面吹牛姨丈,可吹牛的內容都是我干的畅卓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蟋恬,長吁一口氣:“原來是場噩夢啊……” “哼翁潘!你這毒婦竟也來了?” 一聲冷哼從身側響起歼争,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤拜马,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后沐绒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俩莽,經...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年乔遮,在試婚紗的時候發(fā)現(xiàn)自己被綠了扮超。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹋肮,死狀恐怖出刷,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情括尸,我是刑警寧澤巷蚪,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站濒翻,受9級特大地震影響,放射性物質發(fā)生泄漏啦膜。R本人自食惡果不足惜有送,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僧家。 院中可真熱鬧雀摘,春花似錦、人聲如沸八拱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至清蚀,卻和暖如春匕荸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枷邪。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工榛搔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人东揣。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓践惑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘶卧。 傳聞我的和親對象是個殘疾皇子尔觉,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內容

  • Vuex 是什么? Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式芥吟。它采用集中式存儲管理應用的所有...
    skycolor閱讀 817評論 0 1
  • Vuex 狀態(tài)管理模式 在使用vue開發(fā)過程中侦铜,經常會遇到一個狀態(tài)在多個組件之間使用,這時候就需要用vuex來狀態(tài)...
    哭泣哭泣帕拉達閱讀 389評論 0 0
  • Vuex 是什么运沦? Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式泵额。它采用集中式存儲管理應用的所有...
    南崽閱讀 303評論 1 2
  • state: 最底層的初始數(shù)據(jù) getters: 相當于vue的計算屬性,對state數(shù)據(jù)進行處理 携添、擴展 mu...
    唯軒_443e閱讀 905評論 0 0
  • 前言 我們知道Vue組件通訊基本的方式有 子傳父,父傳子,平行兄弟組件通信嫁盲,那么在簡單的應用當中,Vue Stor...
    Echonessy閱讀 382評論 0 1