爲什麼要使用Vuex?
父組件下有多A、B子組件, 子組件之間通訊使用vuex變的簡單方便。
如何引入Vuex?
下載vuex: cnpm install vuex --save
在main.js添加:
import Vuex from 'vuex'
Vue.use( Vuex );
const store = new Vuex.Store({
//待添加
})
new Vue({
el: '#app',
store,
render: h => h(App)
})
核心概念1: State
state就是Vuex中的公共的狀態, 我是將state看作是所有組件的data, 用於保存所有組件的公共數據.
const store = new Vuex.Store({
state:{
products: [
{name: '鼠標', price: 20},
{name: '鍵盤', price: 40},
{name: '耳機', price: 60},
{name: '顯示屏', price: 80}
]
}
})
在子組件A.vue使用
export default {
data () {
return {
products : this.$store.state.products //獲取store中state的數據
}
}
}
核心概念2: Getters
我將getters屬性理解爲所有組件的computed屬性, 也就是計算屬性. vuex的官方文檔也是說到可以將getter理解爲store的計算屬性, getters的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被重新計算。
此時,我們可以在main.js中添加一個getters屬性, 其中的saleProducts對象將state中的價格減少一半(除以2)
//main.js
const store = new Vuex.Store({
state:{
products: [
{name: '鼠標', price: 20},
{name: '鍵盤', price: 40},
{name: '耳機', price: 60},
{name: '顯示屏', price: 80}
]
},
getters:{ //添加getters
saleProducts: (state) => {
let saleProducts = state.products.map( product => {
return {
name: product.name,
price: product.price / 2
}
})
return saleProducts;
}
}
})
B.vue子組件來獲取這個state變化後的值
export default {
data () {
return {
products : this.$store.getters.saleProducts
}
}
}
核心概念3: Mutations
我將mutaions理解爲store中的methods, mutations對象中保存着更改數據的回調函數,該函數名官方規定叫type, 第一個參數是state, 第二參數是payload, 也就是自定義的參數.
下面,我們在main.js中添加mutations屬性,其中minusPrice這個回調函數用於將商品的價格減少payload這麼多, 代碼如下:
核心概念4: Actions
actions 類似於 mutations,不同在於:
actions提交的是mutations而不是直接變更狀態
actions中可以包含異步操作, mutations中絕對不允許出現異步
actions中的回調函數的第一個參數是context, 是一個與store實例具有相同屬性和方法的對象
此時,我們在store中添加actions屬性, 其中minusPriceAsync採用setTimeout來模擬異步操作,延遲2s執行 該方法用於異步改變我們剛纔在mutaions中定義的minusPrice
在 Vue 組件中獲得 Vuex 狀態
那麼我們如何在 Vue 組件中展示狀態呢?由於 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性computed中返回某個狀態:
<div>
<button @click="increment">+1</button>
<input v-model="this.$store.state.count" />
<div>{{count}}</div>
</div>
<script>
computed: {
count () {
return store.state.count
}
}
</script>
//main.js
mutations: { //添加mutations
minusPrice(state, payload) {
let newPrice = state.products.forEach(product => {
product.price -= payload
})
},
increment(state){
state.count++;
console.log('state.count='+state.count)
}