Vue.js學習第十五天——Vuex中各個屬性的使用
今天的學習圍繞一張圖片展開(圖片引用自Vuex官方文檔),當我們的項目比較大時,Vuex爲我們在可以在組件外部管理狀態提供了條件
一、 State
【解釋】狀態的意思,顧名思義,這裏就是存放狀態的地方,簡單來說,就是存放你需要共享的某些變量的地方
【使用】當我們在state中設置了相應的變量後,我們就可以來引用它們了,之前說過,當我們安裝了Vuex後,會在全局生成一個store對象,我們可以使用,我們就可以使用這個store對象來訪問我們的變量,如<h2>{{$store.state.counter}}</h2>
,couter我已經在state中添加了它的值
【相關知識】 State單一狀態樹(Single Source of Truth)又叫做單一數據源,也就是說Vuex中建議我們在Store中存放一個Store對象的實例,這個實例就是數據源,如果數據源特別多,就不容易進行後期的維護和管理,所以最好只有一個Store實例,這就叫做單一狀態樹
二、 Mutations
【解釋】轉變、改變的意思,和Vue實例中的methods屬性差不多,主要存放的是處理數據的各個方法
【使用】在Mutations中定義的各個函數都會有一個參數state,用來獲取相應的數據,可以通過state調用state中存儲的數據,進行相應轉化,比如當我們在一個按鈕中監聽點擊事件調用的那個函數時,函數中需要使用this.$store.commit(Mutations中的函數名);
來調用Mutations中的函數進行處理,在commit中還可以同時提交一個對象交由Mutations處理,例如
// 第一種風格
addStu(){
const info = {
id:1005,
name:'lzx',
age:20
}
//payload
this.$store.commit('addStu',info);
// 第二種風格
jianCoun(num){
this.$store.commit({
type: 'resolveNum',
num,
age:18
})
},
這裏我們傳了一個info對象,這個info對象就被叫做payload,負載、載荷的意思,同時我們可以這麼處理(students是state中的一個數組):
addStu(state,info){
state.students.push(info);
},
值得注意的是,在Vuex中同樣有像Vue中數組的有些方法一樣不是響應式的,因爲Vuex中store狀態的更新唯一方式是提交Mutations,比如state.info['address'] = 'LiShui'
在info對象中添加屬性address,值爲‘LiShui’,我們應該這樣Vue.set(state.info,'address','LiShui');
還有一個delete state.info.age;
也不是響應式的,應該修改爲Vue.delete(state.info,'age');
總之,我們必須遵守一些規則才能做到響應式:1. 提前在store中初始化好所需的屬性;2.當給state中的對象添加新的屬性時使用Vue.set
或是用新對象給就對象重新賦值的方式進行
三、 Getters
【解釋】獲得、得到的意思,和Vue實例中的computed屬性差不多,是對數據進行轉化的地方
【使用】同樣,在getters中定義的各個函數都有一個state參數,除此之外還有一個geter參數,可以獲得自己getter下的其它函數,例如:
moreAge(state){
return state.students.filter(s=>s.age>5);
},
numAge(state,get){
return get.moreAge.length;
},
調用也很簡單
<h2>{{$store.getters.moreAge}}</h2>
<h2>{{$store.getters.numAge}}</h2>
同樣的調用的時候也可以傳入參數例如:
<h2>{{$store.getters.whatAge(30)}}</h2>
處理如下:
whatAge(state){
return age => {
return state.students.filter(s=>s.age>age);
}
}
這種用法注意一下,和靈活,返回可以是一個函數
四、 Actions
【解釋】行動、行爲的意思,在這裏編寫我們的異步代碼,由最開始的那張圖片我們可以知道,當你有一些異步請求時如果我們在 Mutations中處理,我們的Devtools沒辦好很好的跟蹤這個操作什麼時候會很好的完成,所以我們在Actions中編寫我們的異步代碼
【使用】直接貼代碼吧,一下是調用那端的代碼
changeStu(){
// 1. 這種方式第二個參數可以傳函數,但是如果有其他參數就不好用了
// this.$store.dispatch('changeStu', () => {
// console.log('ok');
// })
// 2.既有函數又有其他參數 但是不夠優雅
// this.$store.dispatch('changeStu',{
// message:'hello actions',
// succeed(){
// console.log('已完成');
// }
// })
//3. Promise
this.$store.dispatch('changeStu','hello actions').then(res => {
console.log('裏面已經完成了');
console.log(res);
})
},
以下是處理那端代碼,也就是actions中的代碼:
// context 上下文
changeStu(context,payload){
return new Promise((resolve,reject) => {
setTimeout(() => {
context.commit('changeStu');
console.log(payload);
resolve('11111')
}, 1000);
})
// setTimeout(()=>{
// console.log(payload);
// context.commit('changeStu');
// console.log(payload.message);
// payload.succeed();
// },1000)
}
五、 Modules
【解釋】 模塊的意思,Vue使用的是單一狀態數,那麼也意味着很多狀態都會交給Vuex來管理,當應用變得非常複雜時,store對象就有可能變得相當臃腫,爲了解決這個問題,Vuex允許我們將store分割成模塊,而每一個模塊擁有自己的state mutations actions getters
【使用】代碼如下:
調用端的代碼:
<h2>{{$store.state.a.name}}</h2>
<button @click="updataName">修改名字</button>
<h2>{{$store.getters.aUpdateName}}</h2>
<h2>{{$store.getters.bUpdateName}}</h2>
<h2>{{$store.getters.cUpdateName}}</h2>
<button @click="AsyncUpdataName">異步修改名字</button>
methods中的代碼:
updataName(){
this.$store.commit('updateName','JYQ')
},
AsycUpdataName(){
this.$store.dispatch('AsycUpdateName');
}
module中的代碼
modules:{
a: moduleA,
}
const moduleA = {
state:{
name: 'beanBag'
},
mutations:{
updateName(state,payload){
state.name = payload;
}
},
getters:{
aUpdateName(state){
return state.name + '1'
},
bUpdateName(state,getter){
return getter.aUpdateName + '2'
},
cUpdateName(state,getter,rootState){
return getter.bUpdateName + rootState.counter
}
},
actions:{
AsyncUpdateName(context){
setTimeout(() => {
context.commit('updateName','hqc');
}, 1000);
}
},
}