Vuex
全局狀態(tài)管理器匹摇,可以在項(xiàng)目的任何一個(gè)組件中去獲取和修改来惧,修改可以得到全局響應(yīng)的變量
vue-cli2
項(xiàng)目中安裝vuex,使用npm install vuex --save
安裝成功后隅居,在src目錄下新建一個(gè)store文件,里面創(chuàng)建一個(gè)js文件
在js文件中寫入:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const STORE = {
state: {},
getters: {},
mutations: {},
actions: {}
}
export default new Vuex.Store(STORE)
然后在main.js文件中引入 store 并注冊(cè)到 vue 實(shí)例中
import Vue from 'vue'
import App from './App.vue'
import store from './store' // 引入store
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store, // 注冊(cè)到實(shí)例中
}).$mount('#app')
vuex的文件配置到這里就完成了
現(xiàn)在再回去看store文件里的參數(shù),這幾個(gè)對(duì)象就是vuex五大核心:
State:可全局訪問的對(duì)象
Getter:和vue的computed一樣屿脐,用來實(shí)時(shí)監(jiān)聽state的值的變化(最新狀態(tài))
Mutation:存放改變state值的方法(同步)
Action:觸發(fā)mutations里面的方法(異步)
module:模塊
State
State是存儲(chǔ)在Vuex中的數(shù)據(jù)對(duì)象,和Vue實(shí)例中的data一樣佑钾。只不過State是可以全局訪問的烦粒。
定義stata對(duì)象扰她,直接在state
里面定義 key:val
徒役,它可以定義任意數(shù)據(jù)類型
state: {
name:'State',
num: 1,
arr: ["1","2","3"],
obj: {
ob1:'1',
ob2:'2'
},
bool: true
},
在頁面中獲取state的值 使用this.$store.state
computed: {
state() { return this.$store.state }
},
mounted(){
console.log(this.state)
}
在這里state
通常都是掛載到computed
計(jì)算屬性上忧勿,這樣當(dāng)state的值發(fā)生改變的時(shí)候都能及時(shí)的響應(yīng)。
當(dāng)然也能用到 watch
去監(jiān)聽
這樣就能獲取到在
state
中定義的數(shù)據(jù)
State中的輔助函數(shù) mapState
當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)時(shí)候卸夕,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余。為了解決這個(gè)問題贡羔,我們可以使用 mapState 輔助函數(shù)幫助我們生成計(jì)算屬性
import Vue from 'vue'
// 引入 mapState輔助函數(shù)
import { mapState } from 'vuex'
export default {
computed:{
// 使用對(duì)象展開運(yùn)算符將此對(duì)象混入到外部對(duì)象中
...mapState({
name: state => state.name, // 獲取到state中的name
num: state => state.num, // 獲取到state中的num
ArrObj: state => [state.arr,state.obj] // 獲取到state中的 arr 和 obj
})
},
mounted(){
console.log('name:',this.name)
console.log('num:',this.num)
console.log('ArrObj:',this.ArrObj)
},
}
輸出
Getter
Vuex 允許我們?cè)?store 中定義getter
(可以認(rèn)為是 store 的計(jì)算屬性)乖寒。就像計(jì)算屬性computed
一樣楣嘁,getter
的返回值會(huì)根據(jù)它的依賴被緩存起來逐虚,且只有當(dāng)它的依賴值(state
中的屬性)發(fā)生了改變才會(huì)被重新計(jì)算叭爱。
Getter的作用就是用來實(shí)時(shí)監(jiān)聽state的值的變化
定義Geters對(duì)象
使用 state
作為其第一個(gè)參數(shù)
可以使用其他getter
函數(shù)作為第二個(gè)參數(shù)
state: {
name:'State',
num: 1,
arr: ["1","2","3"],
obj: {
ob1:'1',
ob2:'2'
},
bool: true
},
getters: {
// 獲取state中的name
getName (state) { return state.name }, // 把state作為第一參數(shù)
// 獲取state中的arr
getArr: state => { return state.arr },
// 獲取state中的obj
getObj: state => { return state.obj },
// 獲取getters中的 getArr 和 getObj
getArrObj: (state,getters) => { // 把getters作為第二參數(shù)
return {
"arr":getters.getArr,
"obj":getters.getObj
}
}
},
在頁面中使用getters买雾,使用this.$store.getters
mounted(){
console.log('Getters:',this.$store.getters)
console.log('getArrObj:',this.$store.getters.getArrObj)
}
Getters中的輔助函數(shù) mapGetters
mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性:
import Vue from 'vue'
// 引入 mapGetters 輔助函數(shù)
import { mapGetters } from 'vuex'
export default {
computed:{
// 使用對(duì)象展開運(yùn)算符將此對(duì)象混入到外部對(duì)象中
...mapGetters([
'getName', // 獲取到 getters 中的 getName
'getArr', // 獲取到 getters 中的 getArr
'getArrObj' // 獲取到 getArrObj 中的 getArrObj
])
},
mounted(){
console.log('getName:',this.getName)
console.log('getArr:',this.getArr)
console.log('getArrObj:',this.getArrObj)
},
}
輸出
Mutation
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation嗤军。
使用 state
作為第一個(gè)參數(shù)
state: {
name:'State',
},
mutations: {
newName(state){
return state.name = 'newState'; // 改變state.name的值
}
},
使用 this.$store.commit('方法名')
觸發(fā)mutations中的方法
mounted(){
console.log('name改變前:',this.$store.state.name)
this.$store.commit('newName') // 啟動(dòng)mutations
console.log('name改變后:',this.$store.state.name)
},
輸出
而第二參數(shù)官方解釋叫 提交載荷(Payload)
可以向 store.commit
傳入額外的參數(shù)型雳,即 mutation
的 載荷(payload)
簡單來說就是可以在在第二參數(shù)里傳入額外的參數(shù)
這里還是用name來做例子
state: {
name:'State',
},
mutations: {
newName(state,playload){
// 傳入第二參數(shù)
return state.name = playload;
}
},
mounted(){
// commit傳入第二參數(shù)
this.$store.commit('newName','哈哈哈哈')
console.log('name修改后:',this.$store.state.name)
this.$store.commit('newName',{'name':'啊啊啊啊','age':'116'})
console.log('name修改后:',this.$store.state.name)
},
輸出
在 Vuex 中,mutation 必須是同步函數(shù)
Action
Action 可以包含任意異步操作浪慌,Action的作用就是異步觸發(fā)Mutations
定義action對(duì)象
接收一個(gè)context
參數(shù)和一個(gè)要變化的形參
context
與store
實(shí)例具有相同的方法和屬性权纤,所以他可以執(zhí)行context.commit("")
,也可以使用 context.state
和 context.getters
來獲取 state
和 getters
外邓。
state: {
name:'State'
},
mutations: {
newName(state,playload){
//傳入第二參數(shù)
return state.name = playload;
}
},
actions: {
actionName(context){
// context的作用與組件上的this.$store作用一樣损话,但兩者還是會(huì)有區(qū)別
return context.commit('newName',100000000)
}
}
使用this.$store.dispatch("方法名")
方法執(zhí)行Actions
mounted(){
console.log('name修改前:',this.$store.state.name)
this.$store.dispatch("actionName")
console.log('name修改后:',this.$store.state.name)
},
輸出
同樣Action還支持載荷方法丧枪,傳入第二形參
actions: {
actionName(context,playload){
return context.commit('newName',playload)
}
}
mounted(){
console.log('name修改前:',this.$store.state.name)
this.$store.dispatch("actionName","qazwsxedc")
console.log('name修改后:',this.$store.state.name)
},
輸出
Module
其中 module 的作用是可以把 store 分割成模塊(module)拧烦,每個(gè)模塊擁有自己的 state恋博、mutation私恬、action、getter秦士、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割:
const MODULEA = {
state: {},
getters: {},
mutations: {},
actions: {}
}
const MODULEB = {
state: {},
getters: {},
mutations: {},
actions: {}
}
export default new Vuex.Store({
modules: {
storeA: MODULEA ,
storeB: MODULEB
}
})
主要是為了解決由于使用單一狀態(tài)樹隧土,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí)曹傀,store 對(duì)象就有可能變得相當(dāng)臃腫皆愉。
簡單來說就是可以把vuex模塊化