Vuex 是什么
Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。
判斷是否要使用 Vuex
如果項目中組件比較多,并且組件之間需要共享狀態(tài),那么就需要用到 Vuex。或者說,如果項目沒有使用 Vuex 也依然能夠完成,那么就不需要使用 Vuex 。
Vuex基本使用流程
安裝
npm install vuex
創(chuàng)建store倉庫,并在vue中掛載
// src/store/index.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
const store = new Vuex.Store({
// “Vuex.Store” 首字母要大寫,不要隨意更改
state: {
// state 中是需要記錄的數(shù)據(jù)
number: 1
}
})
export default store
// src/main.js
import store from '@/store'
new Vue({
// ...
store
})
在組件中使用state數(shù)據(jù)
vuex通過computed計算屬性監(jiān)測數(shù)據(jù)的變化,進而影響到所有組件中數(shù)據(jù)的狀態(tài)
計算屬性中使用this.$store.state獲取
computed: {
number () {
return this.$store.state.number
}
}
借助輔助函數(shù)mapState實現(xiàn)
import { mapState } from 'vuex'
computed: {
...mapState([
'number'
])
}
在store中定義mutations,改變state狀態(tài)
new Vuex.Store({
// ...
mutations: {
plus (state) {
state.number++
}
}
})
在各個組件中可以通過提交mutations改變state數(shù)據(jù)
栗子:
// src/App.vue
<template>
<div id="a-com">
<h3>state的number: {{ number }}</h3>
<a-com></a-com>
<b-com></b-com>
</div>
</template>
<script>
import { mapState } from 'vuex'
import ACom from '@/components/ACom
import BCom from '@/components/BCom
export default {
name: 'App',
computed: {
...mapState([
'number'
])
},
components: {
ACom,
BCom
}
}
</script>
// src/components/ACom.vue
<template>
<div id="a">
<h3>A組件的number: {{ number }}</h3>
<button @click="plusNumber">+</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'A',
computed: {
...mapState([
'number'
])
},
methods: {
// 返回需要的mutations函數(shù)
...mapMutaions([
'plus'
]),
plusNumber () {
// 1. 直接通過store提交mutations
// 此處plus是mutations中的方法
// this.$store.commit('plus')
// 2. 使用mapMutations輔助函數(shù) this.plus()
}
}
}
</script>
在src/components/BCom.vue中定義相同的結(jié)構(gòu)

當(dāng)點擊A+或者B+的按鈕時都會觸發(fā)數(shù)據(jù)倉庫state中的number變化
通過vuex我們在不同的組件中共享了數(shù)據(jù),實現(xiàn)了某個組件改變數(shù)據(jù)時,其他組件同時響應(yīng)
Vuex 狀態(tài)管理流程:view => actions => mutations => state => view
栗子:
const store = new Vuex.Store({
state: { // state 用來保存狀態(tài)
num: 88
},
getters: { // 可以對 state 中的數(shù)據(jù)做一些約束
getNum (state) { // 這里傳的參數(shù)是 state
return state.num > 0 ? state.num : 0
}
},
mutations: { // mutations 可以直接改變 state 中的狀態(tài),里面定義改變狀態(tài)的函數(shù)
increase (state) { // 這里傳的參數(shù)是 state
state.num += 10
},
decrease (state) {
state.num -= 10
}
},
actions: { // actions 中只能對 mutations 進行操作,而不能直接改變 state 中的狀態(tài)
increaseAction (context) { // 這里傳的參數(shù)是上下文對象(context)
context.commit('increase') // 使用 context,提交 increase 方法
}, // 這里提交的increase 方法對應(yīng) mutations 中的 increase 方法
decreaseAction (context) {
context.commit('decrease')
}
}
})
獲取 state 中保存的數(shù)據(jù)
this.$store.state.xxx // xxx 為 state 中的鍵值
如上例中:
this.$store.state.num
獲取 getters 中保存的數(shù)據(jù)
this.$store.getters.xxx // xxx 為 getters 中的函數(shù)名
如上例中:
this.$store.getters.getNum
觸發(fā) mutations 中的函數(shù)
this.$store.commit('xxx') // xxx 為函數(shù)名
如上例中:
this.$store.commit('increase')
觸發(fā) actions 中的函數(shù)
this.$store.dispatch('xxx') // xxx 是函數(shù)名
如上例中:
this.$store.dispatch('increaseAction')
mutations 和 actions 的區(qū)別
函數(shù)傳遞的參數(shù)不同
- mutations 中的函數(shù)傳的是 state;
- actions 中的函數(shù)傳的是 context;
觸發(fā)方式不同
- 觸發(fā) mutations 中的函數(shù),通過 this.$store.commit('xxx');
- 觸發(fā) actions 中的函數(shù),通過 this.$store.dispatch('xxx');
mutations 中只能包含同步操作,actions 中可以包含異步操作
mutations
mutations: {
increase (state) {
state.num += 10
},
decrease (state) {
state.num -= 10
}
}
actions
actions: {
increaseAction (context) {
setTimeout(function () { // 異步操作
context.commit('increase')
}, 1000)
},
decreaseAction (context) {
setTimeout(function () {
context.commit('decrease')
}, 1000)
}
}
操作對象不同
- mutations 可以直接操作 state;
- actions 不能直接操作 state,而是操作 mutations。
vuex的應(yīng)用場景
檢測用戶是否登錄
當(dāng)在登錄組件中處理了登錄信息后,存入state倉庫中,可在所有的組件中進行用戶數(shù)據(jù)共享,判斷是否有權(quán)限
非父子組件值傳遞
其實父子組件中也是可以使用vuex,主要看業(yè)務(wù)的復(fù)雜度