先不說原理,直接說使用吧,用著用著就 明白了
A: 需求:
在專案中,元件之間是獨立的,元件之間要想實現通訊,父子之間通訊可以用props選項,但是兄弟之間的通訊就比較複雜
B: 簡單理解:
如果在state中定義一個資料之後,我們可以在專案中的任何一個元件裡獲取和修改,並且我們的修改可以得到全域性的相應變更 比如
let state = {
userList: [], // 使用者列表
}
這個userList裡的資料,可以在全域性使用
複製程式碼
C: vuex種的五個基本屬性
1, 我們可以通過this.$store在vue的元件中獲取vuex的例項
2, State:vuex中的資料來源,可以通過thsi.$store.state獲取在vuex中宣告的全域性變數的值
3, Getter:相當於vue中的computed(計算屬性),可以用於監聽/計算state中值的變化
4, Mutation: vuex中提交更改資料的方法(只能同步執行)
5, Action:
6, Module: 模組化vuex
- 1,先開始使用,在專案中新建一個store資料夾,相當於一個倉庫,在store資料夾下面新建index.js檔案
import Vue from 'vue'
import Vuex from 'vuex' // 引入vuex
Vue.use(Vuex)
const store = new Vuex.Store(); // 例項化
export default store
複製程式碼
- 2, 在main.js裡面引入store,然後全域性註冊一下,這樣就可以在任何元件使用this.$store了
import store from './store' //引入store
new Vue({
el: '#app',
router,
store, //使用store
template: '<App/>',
components: { App }
})
複製程式碼
- 3, 回到store資料夾的index.js檔案,我們宣告一個state變數,賦值給一個物件,裡面定義兩個初始的屬性,然後在例項化的Vuex.Store裡面傳入一個空物件,把宣告的state放進去
說明: vuex使用單一狀態樹,state是唯一資料來源,所以每個瑩瑩僅包含一個store例項,
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = { //要設定的全域性訪問的state物件
showHello: true,
changeNum: 0
//要設定的初始屬性值
}
const store = new Vuex.Store({
state
})
export default store
複製程式碼
說明: 做完這個之後,我們就可以在任何元件裡面使用this.%store.showHello和this.%store.changeNum來獲取定義的值了
- 4,vuex官方提供了一個getter(可以認為是store的計算屬性),想計算屬性一樣,getter的返回值會根據它的一來被快取起來,只有當它的依賴值發生改變才會被重新計算,把他也扔到state裡面
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state={ //要設定的全域性訪問的state物件
showHello: true,
changeNum: 0
//要設定的初始屬性值
}
const getters = { //實時監聽state值的變化(最新狀態)
isShow(state) { //方法名隨意,主要是來承載變化的showHellor的值
return state.showHello
},
getChangedNum() { //方法名隨意,主要是用來承載變化的changeNum的值
return state.changeNum
}
}
const store = new Vuex.Store({
state,
getters
});
export default store;
複製程式碼
- 5, 現在只有定義的state初始值,但是我們需要改變初始值,接下來就是mutation了mutation也是一個物件,這個物件裡面放可以改變state初始值的方法,具體的就是:給裡面的方法傳入引數或者額外的其他引數,理由vue的雙向資料驅動進行值得改變,把定義好的mutation也扔進Vuex.Store裡面.
更改vuex的store中的狀態的唯一方法就是提交mutation,vuex中的mutation非常類似事件,就是每個mutation都有一個字串的事件型別(type)和一個回撥函式(handler),這個回撥函式就是我們實際進行狀態更改的地方,並且它會接受state作為第一個引數
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state={ //要設定的全域性訪問的state物件
showHellor: true,
changeNum:0
//要設定的初始屬性值
};
const getters = { //實時監聽state值的變化(最新狀態)
isShow(state) { //承載變化的showHellor的值
return state.showHellor
},
getChangedNum(){ //承載變化的changebleNum的值
return state.changeNum
}
};
const mutations = {
show(state) { //自定義改變state初始值的方法,這裡面的引數除了state之外還可以再傳額外的引數(變數或物件);
state.showHellor = true;
},
hide(state) { //同上
state.showHellor = false;
},
newNum(state, sum){ //同上,這裡面的引數除了state之外還傳了需要增加的值sum
state.changeNum += sum;
}
};
複製程式碼
-
6, 這個時候就可以用 this.$store.commit('show') 或
this.$store.commit('hide') 以及
this.$store.commit('newNum',6)在別的元件裡面進行改變showHello和changeNum的值了
-
7, 但是在vuex中,mutation裡的方法都是同步,意思就是,比如這個this.$store.commit('newNum',sum)方法,
兩個元件裡用執行得到的值,每次都是一樣的,顯然不是我們需要的,vuex還提供了actions,把action也放入Vuex.Store裡面,這個actions也是物件變數,裡面的Action方法,可以包含任意非同步操作,這裡的非同步就是用非同步發出mutation裡面的方法,action裡面的自定義函式接受一個context引數和要變化的形參
// 實踐中我們可以用es6引數解構來剪髮程式碼
actions: {
increment ({ commit }) {
commit('increment')
}
}
複製程式碼
context和store例項具有相同的屬性和方法,可以呼叫context.commit()提交一個mutation,或者通過context.state和context.getter來偶去state和getter
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state={ //要設定的全域性訪問的state物件
showHello: true,
changeNum:0
//要設定的初始屬性值
};
const getters = { //實時監聽state值的變化(最新狀態)
isShow(state) { //承載變化的showHello的值
return state.showHello
},
getChangedNum(){ //承載變化的changebleNum的值
return state.changeNum
}
};
const mutations = {
show(state) { //自定義改變state初始值的方法,這裡面的引數除了state之外還可以再傳額外的引數(變數或物件);
state.showHello = true;
},
hide(state) { //同上
state.showHello = false;
},
newNum(state,sum){ //同上,這裡面的引數除了state之外還傳了需要增加的值sum
state.changeNum += sum;
}
};
const actions = {
hideHello(context) { //自定義觸發mutations裡函式的方法,context與store 例項具有相同方法和屬性
context.commit('hide');
},
showHello(context) { //同上註釋
context.commit('show');
},
getNewNum(context, num){ //同上註釋,num為要變化的形參
context.commit('newNum', num)
}
};
const store = new Vuex.Store({
state,
getters,
mutations,
actions
});
export default store;
複製程式碼
action 通過 store.dispatch 方法觸發
在外部元件進行全域性執行actions裡面的方法的時候,你只需要執行
this.$store.dispatch('hideHello')
或this.$store.dispatch('showHello')
以及this.$store.dispatch('getNewNum', 6) //6要變化的實參