- 安裝
npm install vuex --save
//或
yarn add vuex
- 使用步驟
- 創(chuàng)建store文件夾
//store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
products: [
{ name: "馬云", price: 200 },
{ name: "馬化騰", price: 100 },
{ name: "馬冬梅", price: 20 },
{ name: "馬蓉", price: 10 }
]
}
});
//注意new Vuex.Store的Store的S是大寫,否則報錯為
Uncaught TypeError: vuex__WEBPACK_IMPORTED_MODULE_1__.default.store is not a constructor
- 在main.js中引入store
import {store} from './store/store';
new Vue({
store,
el:"#app",
render:h => h(App)
})
- 使用數(shù)據(jù)
//在組件中
//product-list-one.vue中利用computed屬性獲取store中的數(shù)據(jù)
export default {
computed:{
products(){
return this.$store.state.products;
}
}
}
在完成數(shù)據(jù)初步渲染之后在組件一種實現(xiàn)改變商品價格的操作
首先獲取需要改變的數(shù)據(jù),然后在計算屬性中對數(shù)據(jù)進行改變
computed: {
products() {
return this.$store.state.products;
},
saleProducts() {
let saleProducts = this.$store.state.products.map(product => {
return {
name: "**" + product.name + "**",
price: product.price / 2
};
});
return saleProducts;
}
}
//將遍歷對象改為saleProducts
<li v-for="(item,index) in saleProducts" :key="index"></li>
但對于多個組價共用次方法則多次復(fù)制比較麻煩,需改為以下方式將方法抽離到store.js中的getters
在store.js中
getters:{
saleProducts:(state) => {
let saleProducts = state.products.map(product => {
return {
name: "**" + product.name + "**",
price: product.price / 2
};
});
return saleProducts;
}
}
實現(xiàn)商品降價功能
- 在vue中只需在methods中添加一個方法
methods:{
reducePrice(){
this.$store.state.products.forEach(product => {
product.price -= 1;
})
}
}
- 更改Vuex的store中的狀態(tài)的唯一方法是提交mutation,Vuex中的mutation非常類似于事件,沒個mutation都有一個字符串的事件類型[type]和一個回調(diào)函數(shù),這個回調(diào)函數(shù)就是我們實際運行狀態(tài)更改的地方,并且他會接受state作為第一個參數(shù)。
一般在觸發(fā)事件時才使用mutation,如果是想要獲取數(shù)據(jù)時就使用getters,想要存儲數(shù)據(jù)時就用state,
//store.js
//觸發(fā)事件,改變數(shù)據(jù)
mutations: {
reducePrice: state => {
state.products.forEach(product => {
product.price -= 1;
});
}
}
//在組件中使用時用commit激活事件,事件觸發(fā)的事件名字要與store中的事件名字相同
methods: {
reducePrice() {
this.$store.commit("reducePrice");
}
}
vueX還兼容嚴格模式。
Actions
Actions提交的是mutation,而不是直接變更的數(shù)據(jù)狀態(tài)。
如果實現(xiàn)異步操作應(yīng)該在Action中實現(xiàn)。
Action是通過store.dispatch觸發(fā)的。
//store/store.js
actions: {
reducePrice: context => {
setTimeout(() => {
context.commit("reducePrice");
}, 2000);
}
}
//組件中
methods: {
reducePrice() {
// this.$store.commit("reducePrice"); //此處commit是直接觸發(fā)mutation中的方法
// 此處應(yīng)調(diào)用actions里的方法
this.$store.dispatch("reducePrice"); //事件名對應(yīng)store中actions中的方法名
}
}
- Actions 可以進行傳參
組件方法中將參數(shù)寫到分發(fā)事件后進行傳遞,store中通過payload參數(shù)進行接收。
//store.js
//觸發(fā)事件,改變數(shù)據(jù)
mutations: {
reducePrice: (state,payload) => {
state.products.forEach(product => {
product.price -= payload;
});
}
},
actions: {
reducePrice: (context, payload) => {
setTimeout(() => {
context.commit("reducePrice",payload);
}, 2000);
}
}
//組件中
methods: {
reducePrice(amount) {
// this.$store.commit("reducePrice"); //此處commit是直接觸發(fā)mutation中的方法
// 此處應(yīng)調(diào)用actions里的方法
this.$store.dispatch("reducePrice",amount); //事件名對應(yīng)store中actions中的方法名
}
}
輔助函數(shù)
mapState
當(dāng)一個組件需要獲取多個狀態(tài)時候,將這些狀態(tài)都聲明為計算屬性會有些重復(fù)和冗余。為了解決這個問題,我們可以使用 mapState 輔助函數(shù)幫助我們生成計算屬性。mapGetters
mapGetters輔助函數(shù)僅僅是將store中的getters映射到局部計算屬性;mapMutations
使用 mapMutations 輔助函數(shù)將組件中的 methods 映射為 store.commit 調(diào)用';mapActions
mapActions輔助函數(shù)將組件的methods映射為store.dispatch調(diào)用,需要先在根節(jié)點注入store;
<script>
import { mapGetters, mapState, mapActions } from "vuex";
export default {
computed:{
// products(){
// return this.$store.state.products;
// },
...mapState(["products"]),
...mapGetters(["saleProducts"])
},
methods:{
...mapMutations([
'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`
// `mapMutations` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射為
`this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
})
...mapActions(["reducePrice"])
}
}
</script>
//如果你想將一個 getter 屬性另取一個名字,使用對象形式:
mapGetters({
doneCount:"doneTodosCount"
})