Vuex是一個(gè)專為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式。它采用集中式儲(chǔ)存管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。
1.1 Vuex的核心概念
1.1.1 state
state 是 Vuex 的核心概念之一,它是一個(gè)存儲(chǔ)數(shù)據(jù)的容器,所有的數(shù)據(jù)都存儲(chǔ)在 state 中。state 是響應(yīng)式的,當(dāng) state 中的數(shù)據(jù)發(fā)生變化時(shí),所有依賴該數(shù)據(jù)的組件都會(huì)自動(dòng)更新。
1.1.2 getters
getters 是一個(gè)計(jì)算屬性,可以對(duì) state 中的數(shù)據(jù)進(jìn)行處理和計(jì)算,然后返回一個(gè)新的數(shù)據(jù)。getters 是響應(yīng)式的,當(dāng) state 中的數(shù)據(jù)發(fā)生變化時(shí),getters 中的數(shù)據(jù)也會(huì)自動(dòng)更新。
1.1.3 mutations
mutations 是一個(gè)同步函數(shù),用于修改 state 中的數(shù)據(jù)。mutations 是同步的,只有通過(guò) mutations 才能修改state中的數(shù)據(jù),否則會(huì)導(dǎo)致數(shù)據(jù)的不一致。
1.1.4 actions
actions 是一個(gè)異步函數(shù),用戶處理異步操作,比如發(fā)送網(wǎng)絡(luò)請(qǐng)求。actions 是異步的,只有通過(guò) actions 才能處理異步操作,否則會(huì)導(dǎo)致數(shù)據(jù)的不一致。
1.2 Vuex的安裝和使用
1.2.1 安裝
npm install vuex --save
1.2.2 創(chuàng)建 store
為了方便模塊管理,Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter,甚至是嵌套子模塊。
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import vuexUse from './vuexUse'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
vuexUse
}
})
這里 vuexUse 是一個(gè)模塊,里面包含了 state、mutation、action、getter 等,代碼如下:
// store/vuexUse.js
export default {
namespaced: true, //開(kāi)啟namespace:true,該模塊就成為命名空間模塊
state: {
num: 1,
msg: 'vuex msg'
},
getters: {
msgNum(state) {
return state.msg + state.num
}
},
mutations: {
addMutation(state) {
state.num++
}
},
actions: {
add({ commit }) {
setTimeout(() => {
commit('addMutation')
}, 2000)
}
}
}
最后在 main.js 中引入store,并new Vue的時(shí)候注入即可。
import store from '@/store/index'
new Vue({ store, render: h => h(App) }).$mount('#app')
到這里,store 就真正創(chuàng)建好了,接下來(lái)就可以在組件中使用了。
1.2.3 組件使用
state,getters 有兩種方式引入到組件中:
mapState:將 store 中的 state 映射到組件中,這樣就可以直接使用 state 中的數(shù)據(jù)了。
mapGetters:將 store 中的 getters 映射到組件中,這樣就可以直接使用 getters 中的方法了。
this.$store.state.vuexUse.num 可以直接使用 state 中的數(shù)據(jù)。
this.$store.getters['vuexUse/msgNum'] 可以直接使用getters中的方法。
組件中有兩種方式執(zhí)行 mutations:
mapMutations:將 store 中的 mutations 映射到組件中,這樣就可以直接使用 mutations 中的方法了。
this.$store.commit('vuexUse/addMutation') 可以直接使用mutations中的方法。
組件中有兩種方式執(zhí)行 actions:
mapActions:將 store 中的 actions 映射到組件中,這樣就可以直接使用 actions 中的方法了。
this.$store.dispatch('vuexUse/add') 可以直接使用 actions 中的方法。
<template>
<div class="wrap">
<div>vuex 使用方式</div>
<div>vuex Store中的num: {{ num }}</div>
<div>$store中的num: {{ $store.state.vuexUse.num }}</div>
<div>vuex Store中的msg: {{ msg }}</div>
<div>vuex Store中的msgNum: {{ msgNum }}</div>
<div>$store中的msgNum: {{ $store.getters['vuexUse/msgNum'] }}</div>
<button type="button" @click="add">觸發(fā)actions</button>
<button type="button" @click="onActions">$store觸發(fā)actions</button>
<button type="button" @click="addMutation">觸發(fā)mutations</button>
<button type="button" @click="onMutations">$store觸發(fā)mutations</button>
</div>
</template>
<script>
import { mapState, mapActions, mapMutations, mapGetters} from "vuex";
export default {
name: "vuexUse",
data() {
return {
};
},
computed: {
...mapState("vuexUse", ["num", "msg"]),
...mapGetters('vuexUse', ["msgNum"]),
},
mounted() {
},
methods: {
...mapActions("vuexUse", ["add"]),
...mapMutations("vuexUse", ["addMutation"]),
onActions() {
console.log(this.$store)
this.$store.dispatch('vuexUse/add')
},
onMutations() {
this.$store.commit('vuexUse/addMutation')
}
}
};
</script>
<style lang="scss" scoped>
.wrap {
padding: 20px;
}
</style>