深入了解Vue中Vuex的用法
前言
Vuex是做什么的?官方的解釋是一個(gè)專為vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式,采用集中式存儲(chǔ)管理應(yīng)用所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化??赐晔遣皇且荒槅?wèn)號(hào),狀態(tài)管理到底是什么?其實(shí)可以將其看成把需要多個(gè)組件共享的變量全部存儲(chǔ)在一個(gè)對(duì)象里,將這個(gè)對(duì)象放在最頂層的vue實(shí)例中,讓其他組件可以使用
安裝
在腳手架里,我們可以通過(guò)創(chuàng)建項(xiàng)目時(shí)勾選vuex的選項(xiàng),系統(tǒng)會(huì)自動(dòng)創(chuàng)建
也可以通過(guò)npm下載npm install vuex --save
配置
新建一個(gè)store文件夾->新建index.js進(jìn)行配置,如果是通過(guò)腳手架創(chuàng)建vuex無(wú)需配置
import Vue from 'vue' import Vuex from 'vuex' //安裝插件 Vue.use(Vuex) //創(chuàng)建對(duì)象 const store=new Vuex.Store({ state:{ }, mutations:{ }, actions:{ }, getters:{ }, modules:{ } }) //導(dǎo)出store對(duì)象 export defaule store
main.js中引入
import store from 'store路徑' new Vue({ el:'#app', store,//Vue.prototype.$store=store render: h => h(App) })
核心概念
在Vuex里有幾個(gè)比較核心的概念:
State
Mutations
Getters
Actoins
Modules
state
state用來(lái)保存狀態(tài),類似data,例如在state里保存一個(gè)count狀態(tài),在任意組件里都可以拿來(lái)使用
state:{ count:10000 } //任意組件里使用,直接展示 <div>{{$store.state.count}}</div>
如何修改state
<div>{{$store.state.count}}</div> <button @click="$store.state.count++">+</button> <button @click="$store.state.count--">-</button>
那么狀態(tài)需要修改時(shí)怎么做呢?很多人會(huì)像上面一樣修改,但是這樣后續(xù)調(diào)試的時(shí)候會(huì)出問(wèn)題的,對(duì)于怎么修改,官方給出了一張圖,如下:
從這張圖的state開(kāi)始順著箭頭走,state提供數(shù)據(jù)給vue組件,vue組件想要修改state得發(fā)布一個(gè)行為actions,發(fā)布之后提交到mutations里,在mutations里修改state。聽(tīng)起來(lái)是不是更復(fù)雜?
為什么官方希望我們這么做,圖里有一個(gè)Devtools,這是vue開(kāi)發(fā)的一個(gè)瀏覽器插件,可以幫助我們記錄修改后的state狀態(tài),可以進(jìn)行跟蹤,但是直接在vue組件里修改state,devtools是記錄不到的
既然devtools是在mutations進(jìn)行記錄追蹤,那actions是干嘛的?其實(shí)我們可以跳過(guò)actions,直接在vue組件里通過(guò)mutations修改state
當(dāng)我們修改的時(shí)候有異步操作的時(shí)候,才需要通過(guò)actions操作完后提交到mutations再進(jìn)行同步操作,因?yàn)閐evtools是跟蹤不到異步操作的
下載devtools瀏覽器插件地址
mutations的基本使用
當(dāng)我們直接去修改state里的狀態(tài)時(shí),devtools并不會(huì)記錄下來(lái)
那我們?nèi)绾瓮ㄟ^(guò)mutations修改?
mutations:{ inc(state){//默認(rèn)傳入一個(gè)state,對(duì)應(yīng)上面的state對(duì)象 state.count++ }, dec(state){ state.count-- } } //方法1 <div> <div>{{$store.state.count}}</div> <button @click="$store.commit('inc')">+</button>//通過(guò)commit方法傳入mutations里定義的方法的名字 <button @click="$store.commit('dec')">-</button> </div> //方法2 methods: { inc(){ this.$store.commit('inc')//通過(guò)commit方法傳入mutations里定義的方法的名字 }, dec(){ this.$store.commit('dec') } }, <div> <div>{{$store.state.count}}</div> <button @click="inc">+</button> <button @click="dec">-</button> </div>
通過(guò)mutations修改state,devtools會(huì)追蹤到并且記錄下來(lái),我們開(kāi)發(fā)時(shí)就可以通過(guò)歷史記錄來(lái)追蹤發(fā)現(xiàn)哪一步發(fā)生了錯(cuò)誤
mutations傳遞參數(shù)
例如:當(dāng)上面案例再添加n個(gè)按鈕去加或減不同的值,我們?cè)偃?chuàng)建n個(gè)方法來(lái)修改,顯然這是不對(duì)的,我們只要定義一個(gè)方法,傳入對(duì)應(yīng)的參數(shù)就可以去實(shí)現(xiàn)這樣的效果,那我們?cè)趺丛趍utations里傳遞參數(shù)呢?
mutations:{ add(state,count){//接收參數(shù) state.count+=count }, subtract(state,count){ state.count-=count } }, methods: { add(count){ this.$store.commit('add',count)//傳遞參數(shù) }, subtract(count){ this.$store.commit('subtract',count) } }, <div> <div>{{$store.state.count}}</div> <button @click="add(5)">+5</button> <button @click="subtract(5)">-5</button> </div>
getters的使用
getters類組件里的計(jì)算屬性,什么是計(jì)算屬性?當(dāng)數(shù)據(jù)經(jīng)過(guò)一系列變化之后再展示就是計(jì)算屬性了,getters也是一樣,那如何使用呢?
getters:{ power(state){//默認(rèn)傳入一個(gè)state,對(duì)應(yīng)上面的state對(duì)象 return state.count*state.count } } <div>平方:{{$store.getters.power}}</div>
actions的使用
上面已經(jīng)說(shuō)過(guò)mutations中的方法必須是同步方法,我們?cè)趍utatoins里用setTimeout模擬一下異步操作看看會(huì)發(fā)生什么
//store.js state:{ name:'aaa' }, mutations:{ updateName(state){ setTimeout(() => { state.name='bbb' }, 1000); } }, //組件 <div>{{$store.state.name}}</div> <button @click="updateName">修改名字</button> methods: { updateName(){ this.$store.commit('updateName') } },
我們可以發(fā)現(xiàn)點(diǎn)擊修改名字按鈕后頁(yè)面顯示的名字發(fā)生了變化,但是devtools沒(méi)有追蹤記錄到,還是'aaa',所以mutations中的方法必須是同步方法
那當(dāng)我們有異步操作的時(shí)候怎么辦?就得通過(guò)actions來(lái)先進(jìn)行異步操作后提交到mutations再進(jìn)行同步操作:
//store.js state:{ name:'aaa' }, mutations:{ updateName(state){ state.name='bbb' } }, actions:{ updateInfo(context){//上下文,當(dāng)前可以理解為store對(duì)象 setTimeout(() => { context.commit('updateName')//不能直接修改,修改state的唯一途徑就是mutations }, 1000); } }, //組件 <div>{{$store.state.name}}</div> <button @click="updateName">修改名字</button> methods: { updateName(){ this.$store.dispatch('updateInfo')//調(diào)用actions里的方法是dispatch } },
修改完之后點(diǎn)擊按鈕等待一秒,devtools可以追蹤記錄到了
modules的使用
當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store對(duì)象就會(huì)變得非常臃腫,為了解決這個(gè)問(wèn)題,Vuex允許我們將store分割成模塊(Modules),每個(gè)模塊擁有自己的state,getters,mutations,actions等,下面是分割模塊的例子:
const moduleA={ state:{ test:'模塊a的state' }, mutations:{}, getters:{}, actions:{} } const moduleB={ state:{}, mutations:{}, getters:{}, actions:{} } const store=new Vuex.Store({ modules:{ a:moduleA, b:moduleB } })
模塊分好之后怎么調(diào)用里面的state,getters之類呢?除state之外其他getters,mutations調(diào)用和之前一樣,但是actions里只能commit自己模塊里的mutaions,state調(diào)用要加上模塊的名字,例如調(diào)用上面的state就是<div>{{$store.state.a.test}}</div>
,為什么會(huì)這樣呢,我們可以打開(kāi)devtools工具看一下就知道了
模塊a會(huì)被放在state里面,所以調(diào)用的時(shí)候要加上模塊的名字
以上就是深入了解Vue中Vuex的用法的詳細(xì)內(nèi)容,更多關(guān)于Vue Vuex的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue移動(dòng)端城市三級(jí)聯(lián)動(dòng)組件使用詳解
這篇文章主要為大家詳細(xì)介紹了vue移動(dòng)端城市三級(jí)聯(lián)動(dòng)組件的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07vue項(xiàng)目中使用ueditor的實(shí)例講解
下面小編就為大家分享一篇vue項(xiàng)目中使用ueditor的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03解決vue-cli項(xiàng)目sourcemap因?yàn)槲募孛麑?dǎo)致的文件定位映射錯(cuò)誤問(wèn)題
這篇文章主要介紹了解決vue-cli項(xiàng)目sourcemap因?yàn)槲募孛麑?dǎo)致的文件定位映射錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Vue實(shí)現(xiàn)移動(dòng)端日歷的示例代碼
工作中遇到一個(gè)需求是根據(jù)日歷查看某一天/某一周/某一月的睡眠報(bào)告,但是找了好多日歷組件都不是很符合需求,只好自己手寫(xiě)一個(gè)日歷組件,順便記錄一下,希望對(duì)大家有所幫助2023-04-04vue路由傳參的基本實(shí)現(xiàn)方式小結(jié)【三種方式】
這篇文章主要介紹了vue路由傳參的基本實(shí)現(xiàn)方式,結(jié)合實(shí)例形式總結(jié)分析了vue.js路由傳參的三種實(shí)現(xiàn)方式,包括params顯示傳參、不顯示參數(shù)以及query顯示參數(shù)傳參,需要的朋友可以參考下2020-02-02vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決
這篇文章主要介紹了vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue router嵌套路由在history模式下刷新無(wú)法渲染頁(yè)面問(wèn)題的解決方法
這篇文章主要介紹了vue router嵌套路由在history模式下刷新無(wú)法渲染頁(yè)面問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01vue3+vant4封裝日期時(shí)間組件方式(年月日時(shí)分秒)
這篇文章主要介紹了vue3+vant4封裝日期時(shí)間組件方式(年月日時(shí)分秒),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10