Vuex的五個屬性

Vuex是什么逞刷?

Vuex是一個專門為Vue.js應用設計的狀態(tài)管理架構嘉涌,統一管理和維護各個vue組件的可變化狀態(tài)。
它有五個核心概念:state夸浅,getters仑最,mutationsactions帆喇,modules警医。

總結

  • state ---> 基本數據
  • getters ---> 從基本數據派生的數據
  • mutations ---> 提交更改數據的方法,同步坯钦!
  • actions ---> 像一個裝飾器
  • modules ---> 模塊化vuex

State

  1. state:Vuex中的基本數據

單一狀態(tài)樹

  • vuex使用單一狀態(tài)樹预皇,即用一個對象就包含了全部的狀態(tài)數據。state作為構造器選項婉刀,定義了所有需要的基本狀態(tài)參數吟温。

在Vue組件中獲得vuex屬性

  • 可以通過Vue的computed獲得Vuex的state,如下:
    在store/index.js中:
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count:56
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

在組件HelloWorld.vue中獲取count屬性

computed:{
    count(){
      return this.$store.state.count
    }
  }
  • mapState輔助函數
  1. 當一個組件需要獲取多個狀態(tài)的時候突颊,將這些狀態(tài)都聲明為計算屬性會有些重復和冗余鲁豪。為了解決這個問題,可以使用到mapState輔助函數來生成計算屬性洋丐,可以少按幾次鍵呈昔。挥等。友绝。
// 在單獨構建的版本中輔助函數為 Vuex.mapState
import { mapState } from "vuex";
export default {
  name: "XXX",
  data() {
    return {
      localCount: 87,
    };
  },
  computed: mapState({
    // 箭頭函數可使代碼更簡練
    count: (state) => state.count,
    // 傳字符串參數 'count' 等同于 `state => state.count`
    countAlias: "count",
    // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數
    countPlusLocalState(state) {
      return state.count + this.localCount;
    },
  }),
};
  1. 當映射的計算屬性的名稱與state的子節(jié)點名稱相同時肝劲,也可以給mapState傳一個字符串數組迁客。
import { mapState } from "vuex";
export default {
  name: "xxx",
  computed: mapState(['count']),
};
  1. 對象展開運算符

mapState函數返回的是一個對象。如何將它與局部計算屬性混合使用呢辞槐?通常掷漱,是需要使用一個工具函數將多個對象合并為一個,這樣可以將最終對象傳給computed屬性榄檬。但有了對象展開運算符卜范,可以大大地簡化寫法:

computed: {
    localComputed() {
      // 本地計算屬性
      return "";
    },
    // 使用對象展開運算符將此對象混入到外部對象中
    ...mapState({
      //...
    }),
  },

組件仍然保有局部狀態(tài)

  • 使用vuex并不意味著需要將所有的狀態(tài)放入vuex。雖然將所有的狀態(tài)放到vuex會使狀態(tài)變化更顯示和易調試鹿榜,但也會使代碼變得冗長和不直觀海雪。
  • 如果有些狀態(tài)嚴格屬于單個組件锦爵,最好還是作為組件的局部狀態(tài)。
  • 這應該根據自己的應用開發(fā)進行權衡和確定奥裸。

getters

  • 從store的state中派生出的狀態(tài)险掀。
  1. getters接收state作為其第一個參數,接收其他getters作為第二個參數湾宙,如不需要樟氢,第二個參數也可以省略。
    store/index.js如下:
export default new Vuex.Store({
  state: {
    count: 56,
  },
  getters: {
    countDouble(state) {
      return state.count * 2
    },
    countDoubleAndDouble(state, getters) {
      return getters.countDouble * 2
    },
  },
  mutations: {},
  actions: {},
  modules: {},
})
  1. 與state一樣侠鳄,也可以通過Vue的computed獲得vuex的getters埠啃。
    組件XXX.vue如下:
computed: {
    count() {
      return this.$store.state.count;
    },
    countDouble() {
      return this.$store.getters.countDouble;
    },
    countDoubleAndDouble() {
      return this.$store.getters.countDoubleAndDouble;
    },
  },

mapGetters 輔助函數

  1. mapGetters輔助函數僅僅是將store中的getters映射到局部計算屬性,與state相似伟恶。
import { mapGetters } from "vuex";
export default {
  name: "XXX",
  computed: {
  // 使用對象展開運算符將 getters 混入 computed 對象中
    ...mapGetters(["countDouble", "countDoubleAndDouble"]),
  },
};
  1. 如果想將一個getter屬性另取名字霸妹,可以使用對象的形式:
...mapGetters({
  double: "countDouble",
  countDoubleAndDouble: "countDoubleAndDouble",
}),

mutations

  • 提交mutations是更改vuex中的狀態(tài)的唯一方法。
  • mutations必須是同步的知押,如果要異步需要使用action
  1. 每個mutations都有一個字符串的事件類型(type)和一個回調函數(handler)叹螟。這個回調函數就是實際進行狀態(tài)更改的地方,并且它會接受state作為第一個參數台盯,提交荷載作為第二個參數(大多數情況下是一個對象罢绽,可以省略)
 const store = new Vuex.Store({
  // 所有的數據都放在state中
  state: {
    count: 45
  },

  // 操作數據,唯一的通道是mutations
  mutations: {
    // 無提交荷載
    increment(state) {
      state.count++
    },
    // 提交荷載
    incrementN(state, obj) {
      state.count += obj.n
    }
  },

  // actions,可以來做異步操作静盅,然后提交給mutations良价,而后再對state(數據)進行操作
  actions: {}
})
  1. 但是不能調用一個mutations handler。這個選項更像是事件注冊:“當觸發(fā)一個類型為increment的mutation時蒿叠,調用此函數明垢。”要喚醒一個mutation handler市咽,需要以相應的 type 調用 store.commit 方法:
// 無提交荷載
store.commit('increment')
// 提交荷載
store.commit('incrementN', {
  n: 100
})

對象風格的提交方式

store.commit({
  type: 'incrementN',
  n: 29
})

mutations 需遵循 Vue 的響應原則

  • 最好提前在 store 中初始化好所有所需屬性痊银;
  • 當需要在對象上添加新屬性時,應該
    • 使用Vue.set(obj,'newProp',123)施绎,或者
    • 以新對象替代老對象溯革。
      例如:利用對象展開運算符可以這樣寫:state.obj = {...state.obj, newProp:123}

mapMutations 輔助函數

  1. 與其他輔助函數相似,可以在組件中使用this.$store.commit('xxx')提交mutation谷醉,或者使用mapMutations輔助函數將組件中的methods映射為store.commit 調用(需要在根節(jié)點注入store)
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'Demo',
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapMutations([
      // 映射 this.increment() 為 this.$store.commit('increment')
      'increment'
    ]),
    ...mapMutations({
      // 映射 this.add() 為  this.$store.commit('increment')
      add: 'incrementN'
    })
  }
}

actions

  • Action類似于mutation致稀,不同在于:
    • Action提交的是mutation,而不是直接變更狀態(tài)俱尼;
    • Action 可以包含任意異步操作抖单。

舉個例子:

const store = new Vuex.Store({
  // 所有的數據都放在state中
  state: {
    count: 45
  },

  // 操作數據,唯一的通道是mutations
  mutations: {
    // 無提交荷載
    increment(state) {
      state.count++
    }
  },

  // actions,可以來做異步操作,然后提交給mutations矛绘,而后再對state(數據)進行操作
  actions: {
    increment(context) {
      setInterval(() => {
        context.commit('increment')
      }, 1000)
    }
  }
})

注意:Action函數接受一個與store實例具有相同方法和屬性的 context 對象躺酒, 因此可以調用 context.commit 來提交一個mutation,或者通過 context.statecontext.getters 來獲取 state 和 getters蔑歌。

分發(fā)actions

  1. Action 通過 store.dispatch 方法觸發(fā):
store.dispatch('increment')

其他與mutations類似的地方

  1. Actions支持同樣的荷載方式和對象方式進行分發(fā):
// 以載荷形式分發(fā)
store.dispatch('incrementN', {
  n: 10
})

// 以對象形式分發(fā)
store.dispatch({
  type: 'incrementN',
  n: 10
})

mapActions 輔助函數

  1. 在組件中可以使用 this.$store.dispatch('xxx) 分發(fā)action羹应;
  2. 也可以使用 mapActions 輔助函數將組件的methods映射為 store.dispatch 調用(需要先在根節(jié)點注入 store)
import { mapActions } from 'vuex'

export default {
  //..
  methods: {
    ...mapActions([
      'incrementN' //映射 this.incrementN() 為 this.$store.dispatch('incrementN')
    ]),
    ...mapActions({
      add: 'incrementN' //映射 this.add() 為 this.$store.dispatch('incrementN')
    })
  }
}

Modules

  1. 使用單一狀態(tài)樹,導致應用的所有狀態(tài)集中到一個很大的對象次屠。但是园匹,當應用變得很大時,store 對象會變得臃腫不堪劫灶。
  2. 為了解決以上問題裸违,Vuex 允許我們將 store 分割到模塊(module)。
  3. 每個模塊擁有自己的 state本昏、mutation供汛、action、getters涌穆、甚至是嵌套子模塊——從上至下進行類似的分割:
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)

  1. 對于模塊內部的 mutationgetter怔昨,接收的第一個參數是模塊的局部狀態(tài),對于模塊內部的 getter,根節(jié)點狀態(tài)會作為第三個參數:
const moduleA = {
  state: { count: 0 },
  mutations: {
    increment (state) {
      // state 模塊的局部狀態(tài)
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    },
    sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }
  }
}
  1. 同樣宿稀,對于模塊內部的 action趁舀,context.state 是局部狀態(tài),根節(jié)點的狀態(tài)是 context.rootState:
const moduleA = {
  // ...
  actions: {
    incrementIfOddOnRootSum (context) {
      if ((context.state.count + context.rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  }
}

參考資料:https://blog.csdn.net/weixin_35955795/article/details/57412181

官方文檔:https://vuex.vuejs.org/zh/guide/

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末祝沸,一起剝皮案震驚了整個濱河市矮烹,隨后出現的幾起案子,更是在濱河造成了極大的恐慌罩锐,老刑警劉巖奉狈,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異涩惑,居然都是意外死亡仁期,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門境氢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟀拷,“玉大人碰纬,你說我怎么就攤上這事萍聊。” “怎么了悦析?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵寿桨,是天一觀的道長。 經常有香客問我,道長亭螟,這世上最難降的妖魔是什么挡鞍? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮预烙,結果婚禮上墨微,老公的妹妹穿的比我還像新娘。我一直安慰自己扁掸,他們只是感情好翘县,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谴分,像睡著了一般锈麸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牺蹄,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天忘伞,我揣著相機與錄音,去河邊找鬼沙兰。 笑死氓奈,一個胖子當著我的面吹牛,可吹牛的內容都是我干的鼎天。 我是一名探鬼主播探颈,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼训措!你這毒婦竟也來了伪节?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤绩鸣,失蹤者是張志新(化名)和其女友劉穎怀大,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體呀闻,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡化借,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了捡多。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓖康。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖垒手,靈堂內的尸體忽然破棺而出蒜焊,到底是詐尸還是另有隱情,我是刑警寧澤科贬,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布泳梆,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏优妙。R本人自食惡果不足惜乘综,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望套硼。 院中可真熱鬧卡辰,春花似錦、人聲如沸邪意。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抄罕。三九已至允蚣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呆贿,已是汗流浹背嚷兔。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留做入,地道東北人冒晰。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓庆捺,卻偏偏與公主長得像承疲,于是被迫代替她去往敵國和親薛闪。 傳聞我的和親對象是個殘疾皇子笆怠,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容

  • Vuex是什么? VueX 是一個專門為 Vue.js 應用設計的狀態(tài)管理架構滞项,統一管理和維護各個vue組件的可變...
    她說東京很熱閱讀 3,788評論 0 0
  • VueX 是一個專門為 Vue.js 應用設計的狀態(tài)管理構架眷茁,統一管理和維護各個vue組件的可變化狀態(tài)(你可以理解...
    Koreyoshi丶閱讀 4,237評論 0 0
  • Vuex的五個核心概念 本文參考自Vue文檔筷凤,說的非常詳細耸携,建議看文檔棵癣。 Vuex是什么? VueX 是一個專門為...
    一二三四五_6ce3閱讀 1,238評論 0 0
  • 1.官方解釋 Vuex是一個專為Vue.js應用程序開發(fā)的狀態(tài)管理模式夺衍。然后Vuex里面有五個特別重要的屬性狈谊,分別...
    新苡米閱讀 811評論 0 1
  • 1、state state就是根據你項目的需求沟沙,自己定義的一個數據結構河劝,里面可以放些通用的狀態(tài)。 const st...
    惜日_d40d閱讀 663評論 0 1