第5講 vuex看完這篇你就會(huì)了(1)

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é)到

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末听隐,一起剝皮案震驚了整個(gè)濱河市补鼻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雅任,老刑警劉巖风范,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沪么,居然都是意外死亡硼婿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)禽车,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)寇漫,“玉大人,你說(shuō)我怎么就攤上這事殉摔≈莞欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵逸月,是天一觀的道長(zhǎng)栓撞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)碗硬,這世上最難降的妖魔是什么瓤湘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮恩尾,結(jié)果婚禮上弛说,老公的妹妹穿的比我還像新娘。我一直安慰自己翰意,他們只是感情好木人,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著冀偶,像睡著了一般虎囚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔫磨,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天淘讥,我揣著相機(jī)與錄音,去河邊找鬼堤如。 笑死蒲列,一個(gè)胖子當(dāng)著我的面吹牛窒朋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝗岖,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼侥猩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了抵赢?” 一聲冷哼從身側(cè)響起欺劳,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铅鲤,沒(méi)想到半個(gè)月后划提,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邢享,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鹏往,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骇塘。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伊履,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出款违,到底是詐尸還是另有隱情唐瀑,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布插爹,位于F島的核電站介褥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏递惋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一溢陪、第九天 我趴在偏房一處隱蔽的房頂上張望萍虽。 院中可真熱鬧,春花似錦形真、人聲如沸杉编。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邓馒。三九已至,卻和暖如春蛾坯,著一層夾襖步出監(jiān)牢的瞬間光酣,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工脉课, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留救军,地道東北人财异。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像唱遭,于是被迫代替她去往敵國(guó)和親戳寸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348