vuex和vue-router一樣都是vue的核心插件死相,它是vue的狀態(tài)管理,對(duì)于跨組件之間的傳值,可以將這些值放到狀態(tài)state里進(jìn)行管理
1. state用法
在第2講里,我已經(jīng)對(duì)src/store這個(gè)文件夾進(jìn)行了改造覆劈,這里先在src/store/state.js里新增一個(gè)值,然后來(lái)講解vuex的用法
const state = {
menuType: 1
}
export default state
這樣就將menuType
放入到了vuex里沛励,讓vuex來(lái)管理這個(gè)值责语,接下來(lái)示范一下在組件中調(diào)用這個(gè)值:
<template>
<section>
{{menuType}}
</section>
</template>
<script>
export default {
computed: {
menuType () {
return this.$store.state.menuType
}
},
data () {
return {
}
},
methods: {
},
}
</script>
那要是放在模塊里的值,應(yīng)該怎樣去獲取呢目派?
再來(lái)看一下坤候,我在第2講中新建的src/store/module/user.js文件,這是一個(gè)模塊企蹭,如果在user.js里新增一個(gè)值白筹,在組件里應(yīng)該怎么獲取呢智末?
const state = {
userName: '張三'
}
const getters = {}
const mutations = {}
const actions = {}
export default {
state,
getters,
mutations,
actions
}
在組件里調(diào)用這個(gè)值
<template>
<section>
{{menuType}}
{{userName}}
</section>
</template>
<script>
export default {
computed: {
menuType () {
return this.$store.state.menuType
},
userName () {
return this.$store.state.user.userName // 調(diào)用模塊里的值
}
},
data () {
return {
}
},
methods: {
},
}
</script>
除了上面提到的組件里獲取值的方式,還可以利用vuex提供的輔助函數(shù)mapSate
來(lái)獲取值:
<template>
<section>
{{menuType}}
{{userName}}
</section>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState({
menuType: state => state.menuType,
userName: state => state.user.userName
})
},
data () {
return {
}
},
methods: {
},
}
</script>
也可以采用簡(jiǎn)寫(xiě)的方式:
computed: {
...mapState({
menuType: state => state.menuType,
userName: state => state.user.userName
})
},
// 簡(jiǎn)寫(xiě)成
computed: {
...mapState({
userName: state => state.user.userName
}),
...mapState([
'menuType',
]),
},
2. getter用法
相當(dāng)于vue里的computed屬性徒河,比如menuType = 1系馆,在我自己的項(xiàng)目里,它代表著菜單類(lèi)型顽照,1代表ping撥測(cè)菜單由蘑,2代表網(wǎng)頁(yè)撥測(cè)菜單,在組件里獲取這個(gè)值的時(shí)候代兵,多次重復(fù)判斷沒(méi)有意義尼酿,咱們就可以放到getter里面進(jìn)行判斷
找到src/store/getter.js:
const getters = {
menuType: state => {
if (state.menuType == 1) {
return 'ping撥測(cè)'
} else {
return '網(wǎng)頁(yè)撥測(cè)'
}
}
}
export default getters
然后在組件里去獲取這個(gè)值:
<template>
<section>
{{menuTypeName}}
</section>
</template>
<script>
export default {
computed: {
menuTypeName () {
return this.$store.getters.menuType
}
},
data () {
return {
}
},
methods: {
},
}
</script>
同樣也可以利用vuex提供的輔助函數(shù)mapGetters
來(lái)獲取值:
computed: {
...mapGetters([
'menuType'
])
},
寫(xiě)在模塊里的getters如何獲取呢?
咱們?cè)趕rc/store/module/user.js新增如下代碼:
const state = {
userName: '張三'
}
const getters = {
userName: state => {
return state.userName + '是管理員'
}
}
const mutations = {}
const actions = {}
export default {
state,
getters,
mutations,
actions
}
利用vuex輔助函數(shù)mapGetters
來(lái)獲取寫(xiě)在模塊里的getters:
<template>
<section>
{{userName}}
</section>
</template>
<script>
import {mapState, mapGetters} from 'vuex'
export default {
computed: {
// menuTypeName () {
// return this.$store.getters.menuType
// },
...mapGetters([
'userName'
])
},
data () {
return {
}
},
methods: {
},
}
</script>
3. mutation用法
前面兩小節(jié)主要講的是如何獲取vuex里的值植影,如果想修改vuex里的值裳擎,就需要通過(guò)commit提交一個(gè)mutation來(lái)修改
找到src/store/mutations.js文件,新增如下代碼:
const mutations = {
SET_MENU_TYPE (state, params) {
state.menuType = params
}
}
export default mutations
然后在組件里調(diào)用這個(gè)mutation:
<template>
<section>
<p>{{menuType}}</p>
<button @click="handleChangeMenuType('2')">修改menuType的值</button>
</section>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState([
'menuType',
]),
},
data () {
return {
}
},
methods: {
handleChangeMenuType (params) {
this.$store.commit('SET_MENU_TYPE', params)
}
},
}
</script>
同樣思币,vuex也提供了輔助函數(shù)mapMutations
來(lái)快速設(shè)置值:
<template>
<section>
<p>{{menuType}}</p>
<button @click="handleChangeMenuType('2')">修改menuType的值</button>
</section>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
export default {
computed: {
...mapState([
'menuType',
]),
},
data () {
return {
}
},
methods: {
...mapMutations([
'SET_MENU_TYPE'
]),
handleChangeMenuType () {
this.SET_MENU_TYPE('2')
}
},
}
</script>
還是同樣的問(wèn)題句惯,放在模塊里的值,應(yīng)該怎樣去提交mutation呢支救?我舉個(gè)例子:
還是在src/store/module/user.js增加如下代碼:
const state = {
userName: '張三'
}
const getters = {
userName: state => {
return state.userName + '是管理員'
}
}
const mutations = {
SET_USER_NAME (state, params) {
state.userName = params
}
}
const actions = {}
export default {
state,
getters,
mutations,
actions
}
然后在組件里調(diào)用這個(gè)寫(xiě)在模塊里的mutation:
<template>
<section>
{{taskId}}
<ul>
<li>今天你吃藥了嘛?</li>
</ul>
<p>{{userName}}</p>
<button @click="handleChangeMenuType">修改menuType的值</button>
</section>
</template>
<script>
import {mapState, mapGetters, mapMutations} from 'vuex'
export default {
computed: {
...mapGetters([
'userName'
])
},
data () {
return {
}
},
methods: {
...mapMutations([
'SET_USER_NAME'
]),
handleChangeMenuType () {
this.SET_USER_NAME('李四')
}
},
}
</script>
4. action用法
上面講的調(diào)用mutation來(lái)修改vuex里的值拷淘,這個(gè)過(guò)程進(jìn)行的是同步操作各墨,如果某個(gè)值需要異步操作才能修改成功,此時(shí)就需要調(diào)用action启涯,它是專(zhuān)門(mén)處理異步請(qǐng)求贬堵,然后改變vuex里的值的
比如,項(xiàng)目里的導(dǎo)航菜單结洼,需要后端動(dòng)態(tài)返回黎做,像請(qǐng)求數(shù)據(jù)這些操作,肯定是異步操作松忍,此時(shí)蒸殿,我就在這里模擬一個(gè)請(qǐng)求,來(lái)修改menuList
這個(gè)值
const state = {
menuType: 1,
menuList: []
}
export default state
首先在src/store/mutations.js里新建一個(gè)mutation:
const mutations = {
SET_MENU_TYPE (state, params) {
state.menuType = params
},
SET_MENU_LIST (state, params) {
state.menuList = params
}
}
export default mutations
其次新建src/api/app.js文件鸣峭,在里面模擬一個(gè)異步請(qǐng)求的接口:
export const getMenuList = () => {
return new Promise((resolve, reject) => {
const err = null
setTimeout(() => {
if (!err) {
resolve({
code: 200,
data: {
menuList: [
{name: '創(chuàng)建任務(wù)'},
{name: '任務(wù)列表'}
]
}
})
} else {
reject(err)
}
})
})
}
找到src/store/actions.js文件宏所,新增如下代碼:
import {getMenuList} from '@/api/app'
const actions = {
updateMenuList ({commit}) {
getMenuList().then(res => {
const {code, data: {menuList}} = res
commit('SET_MENU_LIST', menuList)
}).catch(err => {
console.log(err)
})
}
}
export default actions
題外話:在調(diào)用一個(gè)異步函數(shù),并且接收其返回的值摊溶,可以采用es7的async/await函數(shù)爬骤,寫(xiě)法如下:
import {getMenuList} from '@/api/app'
const actions = {
async updateMenuList({commit}) {
try {
const {code, data: {menuList}} = await getMenuList()
commit('SET_MENU_LIST', menuList)
} catch (err) {
console.log(err)
}
}
}
export default actions
然后在組件里調(diào)用這個(gè)action:
<template>
<section>
<button @click="handleChangeMenuList">異步獲取菜單list</button>
<ul>
<li v-for="(item, index) in menuList" :key="index">{{item.name}}</li>
</ul>
</section>
</template>
<script>
import {mapState, mapGetters, mapMutations} from 'vuex'
export default {
computed: {
...mapState([
'menuList',
]),
},
data () {
return {
}
},
methods: {
handleChangeMenuList () {
this.$store.dispatch('updateMenuList')
}
},
}
</script>
同樣,vuex也提供了輔助函數(shù)mapActions
來(lái)調(diào)用action:
<template>
<section>
<button @click="handleChangeMenuList">異步獲取菜單list</button>
<ul>
<li v-for="(item, index) in menuList" :key="index">{{item.name}}</li>
</ul>
</section>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
computed: {
...mapState([
'menuList',
]),
},
data () {
return {
}
},
methods: {
...mapActions([
'updateMenuList'
]),
handleChangeMenuList () {
this.updateMenuList()
}
},
}
</script>
還是同樣的問(wèn)題莫换,寫(xiě)在模塊里的action如何調(diào)用霞玄?
找到src/api/app.js文件骤铃,新增一個(gè)異步接口:
export const getUserName = () => {
return new Promise((resolve, reject) => {
const err = null
setTimeout(() => {
if (!err) {
resolve({
code: 200,
data: {
name: '李四'
}
})
} else {
reject(err)
}
})
})
}
然后在src/store/module/user.js文件里的actions里新增一個(gè)方法:
import {getUserName} from '@/api/app'
const state = {
userName: '張三'
}
const getters = {
userName: state => {
return state.userName + '是管理員'
}
}
const mutations = {
SET_USER_NAME (state, params) {
state.userName = params
}
}
const actions = {
async getUserName ({commit}) {
try {
const {code, data: {name}} = await getUserName()
commit('SET_USER_NAME', name)
} catch (error) {
console.log(err)
}
}
}
export default {
state,
getters,
mutations,
actions
}
最后在組件里調(diào)用:
<template>
<section>
<button @click="handleChangeMenuList">異步獲取菜單list</button>
<ul>
<li v-for="(item, index) in menuList" :key="index">{{item.name}}</li>
</ul>
<button @click="handleChangeUserName">異步獲取userName</button>
<p>{{userName}}</p>
</section>
</template>
<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
computed: {
...mapState([
'menuList',
]),
...mapGetters([
'userName'
])
},
data () {
return {
}
},
methods: {
...mapMutations([
'SET_USER_NAME'
]),
...mapActions([
'updateMenuList',
'getUserName'
]),
handleChangeMenuList () {
this.updateMenuList()
},
handleChangeUserName () {
this.getUserName()
}
},
}
</script>
以上就是vuex的基本用法,通過(guò)這篇文章坷剧,我相信在項(xiàng)目中使用vuex是沒(méi)有任何問(wèn)題的惰爬,關(guān)于vuex更高級(jí)的用法,可以在下一篇文章中學(xué)到