相比接觸vue的同學們已經(jīng)看了官方文檔了试读。這里我用一個簡單的demo來闡述下vuex的知識點杠纵,雖然簡單,但是容易理解钩骇。也加深自己的記憶比藻。
用腳手架建立個項目vue init webpakc-simple ,安裝下vuex倘屹,這里我新建2個組件productOne,productTwo.
好银亲,如果想在2個組件中引用同一組數(shù)據(jù),笨方法就是在每個組件的data里寫上數(shù)據(jù)纽匙,聰明點可以在根組件中建立數(shù)據(jù)务蝠,通過props傳給子組件。那么這里烛缔,我用vuex來儲存數(shù)據(jù)馏段。通過在根實例中注冊 store 選項赠尾,該 store 實例會注入到根組件下的所有子組件中,且子組件能通過 this.$store 訪問到毅弧。
新建個store文件夾气嫁,里面新建個store.js。這里就是vuex狀態(tài)管理作用的地方够坐。
store.js中
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
}
})
main.js中寸宵,引入store模塊并注冊。
import Vue from 'vue'
import App from './App.vue'
import {store} from './store/store.js'
new Vue({
el: '#app',
store,
render: h => h(App)
})
state
官網(wǎng)上說元咙,state是作為一個單一狀態(tài)樹梯影,用一個對象來包含了全部的應用層級狀態(tài)。至此它便作為一個唯一數(shù)據(jù)源的存在庶香。這也意味著甲棍,每個應用將僅僅包含一個 store 實例。單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段赶掖,在調(diào)試的過程中也能輕易地取得整個當前應用狀態(tài)的快照感猛。
由于vuex的狀態(tài)存儲是響應式的,那么在組件中奢赂,我們就可以用計算屬性來獲取state狀態(tài)头遭。每當 store.state.count 變化的時候, 都會重新求取計算屬性庭惜,并且觸發(fā)更新相關聯(lián)的 DOM敞峭。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products:[
{name:'apple', price: '2'},
{name:'banana', price: '3'},
{name:'pear', price: '4'},
{name:'melon', price: '5'},
]
}
})
兩個組件中的結構大概如下:用計算屬性用this.$state來返回這個狀態(tài)赃磨。
<template>
<div class="product-one">
<h2>product-one</h2>
<ul>
<li v-for="item in product">
<div class="name">{{item.name}}</div>
<div class="price">{{item.price}}</div>
</li>
</ul>
</div>
</template>
<script>
export default {
computed: {
product() {
return this.$store.state.products
}
}
}
</script>
這樣2個組件中的數(shù)據(jù)就可以統(tǒng)一在store.js中管理了。效果如下:
好轧钓,如果現(xiàn)在想改變下數(shù)據(jù)的一些內(nèi)容序厉,比如價格都漲2倍,那該怎么做呢毕箍,此時就用到getters
getter
官網(wǎng)上說弛房,getters就相當于是store的計算屬性,可以處理state的數(shù)據(jù)霉晕,它接受第一個參數(shù)就是state庭再。那么接下來就簡單了,把計算邏輯寫在getters里牺堰,在組件中再獲取getters就行了拄轻。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products:[
{name:'apple', price: '2'},
{name:'banana', price: '3'},
{name:'pear', price: '4'},
{name:'melon', price: '5'},
]
},
getters: {
changeProduct: (state) => {
return state.products.map(val => {
return {
name: '**' + val.name + '--',
price: val.price*2
}
})
return state.products
}
}
})
在子組件中,用計算屬性來獲取getters,并在DOM中遍歷這個計算屬性。
export default {
computed: {
product() {
return this.$store.state.products
},
changeProduct(){
return this.$store.getters.changeProduct
}
}
}
<li v-for="item in changeProduct">
<div class="name">{{item.name}}</div>
<div class="price">{{item.price}}</div>
</li>
可以看到伟葫,2個組件的數(shù)據(jù)都改變了恨搓。
mutation
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調(diào)函數(shù) (handler)。這個回調(diào)函數(shù)就是我們實際進行狀態(tài)更改的地方斧抱,并且它會接受 state 作為第一個參數(shù)
你不能直接調(diào)用一個 mutation handler常拓。這個選項更像是事件注冊:“當觸發(fā)一個類型為 increment 的 mutation 時,調(diào)用此函數(shù)辉浦∨В”要喚醒一個 mutation handler,你需要以相應的 type 調(diào)用 store.commit 方法宪郊。
簡單來說掂恕,就是mutations就類似事件,子組件中用this.$store.commit('事件名')來獲取弛槐。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products:[
{name:'apple', price: '2'},
{name:'banana', price: '3'},
{name:'pear', price: '4'},
{name:'melon', price: '5'},
]
},
getters: {
changeProduct(state){
return state.products.map(val => {
return {
name: '**' + val.name + '--',
price: val.price*2
}
})
return state.products
}
},
mutations: {
decrePrice(state){
state.products.forEach(val => {
val.price -= 1
})
}
}
})
子組件中
methods: {
decrePrice(){
return this.$store.commit('decrePrice')
}
}
action
action和mutation類似懊亡,不同的是,Action 提交的是 mutation乎串,而不是直接變更狀態(tài)店枣。而且Action支持異步。mutation必須同步執(zhí)行叹誉。
Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象鸯两,因此你可以調(diào)用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters桂对。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products:[
{name:'apple', price: '2'},
{name:'banana', price: '3'},
{name:'pear', price: '4'},
{name:'melon', price: '5'},
]
},
getters: {
changeProduct(state){
return state.products.map(val => {
return {
name: '**' + val.name + '--',
price: val.price*2
}
})
return state.products
}
},
mutations: {
decrePrice(state){
state.products.forEach(val => {
val.price -= 1
})
}
},
actions: {
decrePriceAction(context){
setTimeout(()=>{
context.commit('decrePrice')
}, 2000)
}
}
})
子組件中,用this.$store.dispatch('action的名字')來獲取甩卓。
methods: {
decrePrice(){
// return this.$store.commit('decrePrice')
return this.$store.dispatch('decrePriceAction')
}
}
好鸠匀,一些基本的就這樣蕉斜,其它的可以去官網(wǎng)看哦~