[toc]
Vuex
-
Vuex是一個為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式
- 采用集中存儲管理應(yīng)用的所有組件的狀態(tài)
-
管理什么狀態(tài)?
- 多個頁面間共享的殃姓,如用戶登錄狀態(tài)袁波,用戶名稱,頭像蜗侈,地理位置信息篷牌,商品的收藏,購物車中的商品
//router/index.js import Vuex from 'vuex' Vue.use(Vuex) // 安裝插件踏幻,會去調(diào)用插件的install方法 const store = new Vuex.store({ state: { counter: 0 }, mutations: { increment(state){ //默認有一個參數(shù)state state.counter++ }, decrement(state){ state.counter-- } }, actions: { }, getters: { }, modules: { } }) export default store //組件中調(diào)用 <button @click="add"></button> methods: { add(){ this.$store.commit('increment') } }
Vuex是一個全局的單例模式
Vuex核心概念
-
State
- 單一狀態(tài)樹:所有狀態(tài)信息都保存在一個store中
-
Getters
當(dāng)需要從store中獲取一些state變異后的狀態(tài)時使用
const store = new Vuex.store({ state: { counter: 0 }, getters: { powerCounter(state){ return state.counter**2 } } } //使用 {{$state.getters.powerCounter}}
const store = new Vuex.store({ state: { counter: 0, students: [ {name: 'aaa', age:10}, {name: 'bbb', age:20}, {name: 'ccc', age:30}, {name: 'ddd', age:40}, ] }, getters: { powerCounter(state){ return state.counter**2 }, //獲取大于20歲的學(xué)生 more20Stus(state){ return state.students.filter(s=>s.age>20) }, //獲取大于20歲的學(xué)生的個數(shù) (getters可以作為參數(shù)傳入) more20StusLen(state, getters){ return getters.more20Stus.length }, //如果想自定義傳入age moreAgeStus(state){ return function(age){ return state.students.filter(s=>s.age>age) } } } } //使用 {{$state.getters.powerCounter}} {{$state.getters.more20Stus}} {{$state.getters.more20StusLen}} {{$state.getters.moreAgeStus(30)}}
-
Mutation
Vuex的store狀態(tài)更新的唯一方式:提交Mutation
-
Mutation主要包括兩部分
- 字符串的事件類型(type)
- 一個回調(diào)函數(shù)(handler)枷颊,該回調(diào)函數(shù)的第一個參數(shù)就是state
-
傳遞參數(shù)
- 參數(shù)被稱為mutation的載荷(payload)
//router/index.js import Vuex from 'vuex' //普通提交風(fēng)格 Vue.use(Vuex) // 安裝插件,會去調(diào)用插件的install方法 const store = new Vuex.store({ state: { counter: 0 }, mutations: { incrementCount(state, count){ state.counter+=count } } }) export default store //組件中調(diào)用 <button @click="add"></button> methods: { add(){ this.$store.commit('incrementCount', count) } } //特殊提交風(fēng)格 const store = new Vuex.store({ state: { counter: 0 }, mutations: { incrementCount(state, payload){ state.counter += payload.count } } }) export default store //組件中調(diào)用 <button @click="add"></button> methods: { add(){ this.$store.commit({ type: 'incrementCount', count }) } }
-
mutation響應(yīng)規(guī)則
- 提前在store中初始化好所需的屬性
- 當(dāng)給state的對象添加新屬性時该面,使用Vue.set(obj, key, value),當(dāng)刪除屬性時夭苗,使用Vue.delete(obj, key)
-
Mutation常量
//router/index.js import Vuex from 'vuex' import {INCREMENT, DECREMENT} from 'mutation-types' Vue.use(Vuex) // 安裝插件,會去調(diào)用插件的install方法 const store = new Vuex.store({ state: { counter: 0 }, mutations: { [INCREMENT](state){ //默認有一個參數(shù)state state.counter++ }, [DECREMENT](state){ state.counter-- } }, }) export default store //組件中調(diào)用 import {INCREMENT} from 'mutation-types' <button @click="add"></button> methods: { add(){ this.$store.commit(INCREMENT) } } //mutation-types.js export const INCREMENT = 'increment' export const DECREMENT = 'decrement'
-
VueX要求Mutation中的方法必須是同步方法
- 主要原因是使用devtools時隔缀,devtools可以幫助我們捕捉mutation的快照
- 但是如果是異步操作题造,那么devtools不能很好地追蹤這個操作什么時候會被完成
- 不要在mutation中進行異步操作
-
Action
-
Action類似于Mutation,是用來代替Mutation進行異步操作的
//router/index.js import Vuex from 'vuex' import {INCREMENT, DECREMENT} from 'mutation-types' Vue.use(Vuex) // 安裝插件猾瘸,會去調(diào)用插件的install方法 const store = new Vuex.store({ state: { info: {name: 'aaa', age: 18} }, mutations: { updateInfo(state){ state.info = 'bbb' } }, actions: { aupdateInfo(context){ //默認攜帶context參數(shù) return new Promise((resolve, reject)=>{ setTimeout(()=>{ context.commit('updateInfo') }, 1000) resolve() }) } } }) export default store //組件中調(diào)用 <button @click="add"></button> methods: { update(){ this.$store.dispatch('aupdateInfo').then(()=>{console.log('修改完成')}) //不帶參數(shù) this.$store.dispatch('aupdateInfo', payload) //攜帶參數(shù) } }
-
-
Module
- Vue使用單一狀態(tài)樹晌梨,這樣當(dāng)應(yīng)用變得復(fù)雜時桥嗤,store對象可能變得非常臃腫,為了解決這個問題仔蝌,Vuex允許我們將store分割成模塊,每個模塊擁有自己的state荒吏、mutations敛惊、actions、getters等