只講操作,不談原理,適合工作用,不適合面試
一個最基本的vuex可以由一個js文件來實現(xiàn),也是我們使用腳手架初始化vue項目默認生成的模式,一個最基本的vuex包括state、mutations、actions,其中actions可以用來寫異步代碼,而mutations只能寫同步代碼,所以在一些更簡單的項目中,actions都可以不用用到。但一個vuex的完整模塊包括:state、mutations、actions、getters、modules,其中getters可以看作在vuex中的計算屬性,modules就是一些子模塊,在一些大型項目中對業(yè)務(wù)進行拆分。

下面我從最簡單的模式到使用模塊,再到使用vuex的map語法糖對vuex的操作進行演示一遍:
不使用模塊的基礎(chǔ)模式
先看看vuex相關(guān)的文件夾,放在src下的store文件夾,里面有一個index.js文件,為vuex的入口,如果不使用模塊,可以將所有相關(guān)代碼寫在index.js文件里面,下面是最基礎(chǔ)的index.js文件演示:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
mainname: 'main'
},
getters: {
getMainname: (state) => {
return state.mainname
}
},
mutations: {
setMainname: (state, data) => {
state.mainname = data
}
},
actions: {
asyncSetMainname: ({ commit }, data) => {
commit('setMainname', data)
}
}
})
可以看到除了modules,其他屬性都使用到了。其中mutations的方法就是直接修改state里面的變量,而actions是通過提交mutations去修改state,而不能直接修改state,actions中的方法的第一個參數(shù)是一個context上下文對象,可以通過context.commit提交mutations,上面的代碼我將它解構(gòu)。
下面是在組件中的操作:
獲取state:
this.$store.state.mainname // main
提交mutations:
this.$store.commit('setMainname', 'main111') // 參數(shù)為mutations方法名,數(shù)據(jù)
提交actions:
this.$store.dispatch('asyncSetMainname', 'main') // 參數(shù)為actions方法名,數(shù)據(jù)
獲取getters:
this.$store.getters.getMainname // main
一般寫在計算屬性中:
computed:{
mainname() {
return this.$store.getters.getMainname
}
}
這就是最基礎(chǔ)的vuex用法。
使用模塊
如果要將vuex拆分成幾個模塊,一般在index.js同級下新建一個modules文件夾,假如我現(xiàn)在拆分出一個叫user的模塊,目錄結(jié)構(gòu)就變成:

vuex的子模塊同樣包含state、mutations、actions、getters這些屬性,下面是user.js的代碼:
const state = {
username: 'user'
}
const getters = {
getUsername: (state) => {
return state.username
}
}
const mutations = {
setUsername: (state, data) => {
state.username = data
}
}
const actions = {
asyncSetUsername: ({ state, commit }, data) => {
commit('setUsername', data)
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
主體內(nèi)容與入口文件index.js基本一致,最后將所有屬性導(dǎo)出,同時要導(dǎo)出一個namespaced為true,為開啟命名空間,以免混亂,然后在index.js中將這個模塊引入,下面是改動后的index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
mainname: 'main'
},
getters: {
getMainname: (state) => {
return state.mainname
}
},
mutations: {
setMainname: (state, data) => {
state.mainname = data
}
},
actions: {
asyncSetMainname: ({ state, commit }, data) => {
commit('setMainname', data)
}
},
modules: {
user
}
})
現(xiàn)在實際上我的vuex是有兩個模塊,一個index主模塊,一個user模塊,那在組件中如何操作呢:
獲取state:
如果和上面的寫法一樣的話,獲取的是index主模塊中的state變量
如果想要獲取user模塊中的state,需要在后面加上模塊名稱
// 默認
this.$store.state.mainname // main
// 獲取子模塊
this.$store.state.user.username // user
提交mutations:
和獲取state的邏輯一樣,不加模塊名稱提交的是index中的mutations,要提交子模塊中的mutations就得加上模塊名
this.$store.commit('user/setUsername', 'user111') // 有點像url寫法,在方法名稱前加上模塊名
如果不加模塊名,會去index.js中找這個mutations方法,找不到就會報錯
this.$store.commit('setUsername', 'user111') // 報錯
提交actions,邏輯一樣:
this.$store.dispatch('user/asyncSetUsername', 'user111')
獲取getters:
computed:{
mainname() {
return this.$store.getters['user/getUsername']
}
}
到這里vuex的基本操作就都說完了,包括不帶模塊的,帶模塊的,下面是使用vuex自帶的map語法糖對操作進行簡化。
使用vuex的map語法糖對操作進行簡化
我們在組件中操作vuex,都得通過this.$store點點點,看起來比較繁瑣,vuex提供了vuex和組件方法進行映射的語法糖,下面我演示一下這些map語法糖的寫法:
在組件中,先從vuex中引入幾個方法:
import { mapMutations, mapActions, mapGetters } from 'vuex'
從名字就可以看出就是和mutations、actions、getters在組件中做映射,下面先看不使用模塊的情況,先從
mapMutations開始演示:
mapMutations是一個方法,返回一個對象,對象里面就是vuex里面的mutations方法,所以在和組件做映射時,要寫在methods中,然后把這個對象解構(gòu):
methods: {
// mapMutations可以接收一個數(shù)組為參數(shù),數(shù)組項就是vuex里面mutations方法的名稱
...mapMutations([
'setMainname'
]),
然后在別的方法中執(zhí)行:
fn() {
this.setMainname('mainname1111')
}
}
上面的寫法就相當于:
methods: {
fn() {
this.$store.commit('setMainname', 'main1111')
}
}
不僅可以映射到組件中的方法,還可以在組件中修改mutations方法的名稱:
methods: {
// 將mapMutations的參數(shù)從數(shù)組改成對象,key值為自定義的方法名,value中為原來mutations方法的名稱
...mapMutations({
setMainnamePro: 'setMainname'
}),
fn() {
this.setMainnamePro('main1111')
}
}
mapActions和mapMutations用法一模一樣,不改變actions方法名稱時參數(shù)傳數(shù)組,改變actions方法名稱時參數(shù)傳對象:
methods: {
...mapActions({
asyncSetMainnamePro: 'asyncSetMainname'
}),
fn() {
this.asyncSetMainnamePro('main111')
}
}
相當于:
methods: {
fn() {
this.$store.dispatch('asyncSetMainname', 'main111')
}
}
mapGetters道理也是一樣,只不過是寫在computed中:
computed: {
...mapGetters([
'getMainname'
])
}
在別的地方用的話跟使用普通計算屬性一樣,注意后面沒有括號:
this.getMainname
同樣可以修改名稱,同樣是參數(shù)把數(shù)組改成對象:
computed: {
...mapGetters({
mainname: 'getMainname'
})
}
在別的地方:
this.mainname
幾個map的基本用法就說完了,上面說的是不用模塊的,也就是拿的都是index.js里面的屬性,那如果要拿user模塊里面的屬性呢,其實也非常簡單,只需要在幾個map方法的第一個參數(shù)寫上模塊名稱就可以,其他用法一模一樣:
...mapMutations('user', [
'setUsername'
])
...mapActions('user', [
'asyncSetUsername'
])
...mapGetters('user', [
'getUsername'
])
同樣把第二個參數(shù)寫成對象就可以自定義vuex里面方法的名稱,用法與上面一樣。
這就是本次超人鴨分享的vuex一些操作寫法,主要是當用到模塊與map語法糖時,在組件中如何操作。歡迎大家指教哦。