深入了解Vue中Vuex的用法
前言
Vuex是做什么的?官方的解釋是一個專為vue.js應用程序開發(fā)的狀態(tài)管理模式,采用集中式存儲管理應用所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化??赐晔遣皇且荒槅柼?,狀態(tài)管理到底是什么?其實可以將其看成把需要多個組件共享的變量全部存儲在一個對象里,將這個對象放在最頂層的vue實例中,讓其他組件可以使用
安裝
在腳手架里,我們可以通過創(chuàng)建項目時勾選vuex的選項,系統(tǒng)會自動創(chuàng)建

也可以通過npm下載npm install vuex --save
配置
新建一個store文件夾->新建index.js進行配置,如果是通過腳手架創(chuàng)建vuex無需配置
import Vue from 'vue'
import Vuex from 'vuex'
//安裝插件
Vue.use(Vuex)
//創(chuàng)建對象
const store=new Vuex.Store({
state:{
},
mutations:{
},
actions:{
},
getters:{
},
modules:{
}
})
//導出store對象
export defaule storemain.js中引入
import store from 'store路徑'
new Vue({
el:'#app',
store,//Vue.prototype.$store=store
render: h => h(App)
})核心概念
在Vuex里有幾個比較核心的概念:
StateMutationsGettersActoinsModules
state
state用來保存狀態(tài),類似data,例如在state里保存一個count狀態(tà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)需要修改時怎么做呢?很多人會像上面一樣修改,但是這樣后續(xù)調(diào)試的時候會出問題的,對于怎么修改,官方給出了一張圖,如下:

從這張圖的state開始順著箭頭走,state提供數(shù)據(jù)給vue組件,vue組件想要修改state得發(fā)布一個行為actions,發(fā)布之后提交到mutations里,在mutations里修改state。聽起來是不是更復雜?
為什么官方希望我們這么做,圖里有一個Devtools,這是vue開發(fā)的一個瀏覽器插件,可以幫助我們記錄修改后的state狀態(tài),可以進行跟蹤,但是直接在vue組件里修改state,devtools是記錄不到的

既然devtools是在mutations進行記錄追蹤,那actions是干嘛的?其實我們可以跳過actions,直接在vue組件里通過mutations修改state

當我們修改的時候有異步操作的時候,才需要通過actions操作完后提交到mutations再進行同步操作,因為devtools是跟蹤不到異步操作的
下載devtools瀏覽器插件地址
mutations的基本使用
當我們直接去修改state里的狀態(tài)時,devtools并不會記錄下來

那我們?nèi)绾瓮ㄟ^mutations修改?
mutations:{
inc(state){//默認傳入一個state,對應上面的state對象
state.count++
},
dec(state){
state.count--
}
}
//方法1
<div>
<div>{{$store.state.count}}</div>
<button @click="$store.commit('inc')">+</button>//通過commit方法傳入mutations里定義的方法的名字
<button @click="$store.commit('dec')">-</button>
</div>
//方法2
methods: {
inc(){
this.$store.commit('inc')//通過commit方法傳入mutations里定義的方法的名字
},
dec(){
this.$store.commit('dec')
}
},
<div>
<div>{{$store.state.count}}</div>
<button @click="inc">+</button>
<button @click="dec">-</button>
</div>通過mutations修改state,devtools會追蹤到并且記錄下來,我們開發(fā)時就可以通過歷史記錄來追蹤發(fā)現(xiàn)哪一步發(fā)生了錯誤

mutations傳遞參數(shù)
例如:當上面案例再添加n個按鈕去加或減不同的值,我們再去創(chuàng)建n個方法來修改,顯然這是不對的,我們只要定義一個方法,傳入對應的參數(shù)就可以去實現(xiàn)這樣的效果,那我們怎么在mutations里傳遞參數(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類組件里的計算屬性,什么是計算屬性?當數(shù)據(jù)經(jīng)過一系列變化之后再展示就是計算屬性了,getters也是一樣,那如何使用呢?
getters:{
power(state){//默認傳入一個state,對應上面的state對象
return state.count*state.count
}
}
<div>平方:{{$store.getters.power}}</div>
actions的使用
上面已經(jīng)說過mutations中的方法必須是同步方法,我們在mutatoins里用setTimeout模擬一下異步操作看看會發(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)點擊修改名字按鈕后頁面顯示的名字發(fā)生了變化,但是devtools沒有追蹤記錄到,還是'aaa',所以mutations中的方法必須是同步方法

那當我們有異步操作的時候怎么辦?就得通過actions來先進行異步操作后提交到mutations再進行同步操作:
//store.js
state:{
name:'aaa'
},
mutations:{
updateName(state){
state.name='bbb'
}
},
actions:{
updateInfo(context){//上下文,當前可以理解為store對象
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
}
},修改完之后點擊按鈕等待一秒,devtools可以追蹤記錄到了

modules的使用
當應用變得非常復雜時,store對象就會變得非常臃腫,為了解決這個問題,Vuex允許我們將store分割成模塊(Modules),每個模塊擁有自己的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>,為什么會這樣呢,我們可以打開devtools工具看一下就知道了

模塊a會被放在state里面,所以調(diào)用的時候要加上模塊的名字
以上就是深入了解Vue中Vuex的用法的詳細內(nèi)容,更多關(guān)于Vue Vuex的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決vue-cli項目sourcemap因為文件重名導致的文件定位映射錯誤問題
這篇文章主要介紹了解決vue-cli項目sourcemap因為文件重名導致的文件定位映射錯誤問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
vue路由傳參的基本實現(xiàn)方式小結(jié)【三種方式】
這篇文章主要介紹了vue路由傳參的基本實現(xiàn)方式,結(jié)合實例形式總結(jié)分析了vue.js路由傳參的三種實現(xiàn)方式,包括params顯示傳參、不顯示參數(shù)以及query顯示參數(shù)傳參,需要的朋友可以參考下2020-02-02
vue使用Print.js打印頁面樣式不出現(xiàn)的解決
這篇文章主要介紹了vue使用Print.js打印頁面樣式不出現(xiàn)的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
vue router嵌套路由在history模式下刷新無法渲染頁面問題的解決方法
這篇文章主要介紹了vue router嵌套路由在history模式下刷新無法渲染頁面問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

