- 安装
npm install vuex --save
//或
yarn add vuex
- 使用步骤
- 创建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)
})
- 使用数据
//在组件中
//product-list-one.vue中利用computed属性获取store中的数据
export default {
computed:{
products(){
return this.$store.state.products;
}
}
}
在完成数据初步渲染之后在组件一种实现改变商品价格的操作
首先获取需要改变的数据,然后在计算属性中对数据进行改变
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>
但对于多个组价共用次方法则多次复制比较麻烦,需改为以下方式将方法抽离到store.js中的getters
在store.js中
getters:{
saleProducts:(state) => {
let saleProducts = state.products.map(product => {
return {
name: "**" + product.name + "**",
price: product.price / 2
};
});
return saleProducts;
}
}
实现商品降价功能
- 在vue中只需在methods中添加一个方法
methods:{
reducePrice(){
this.$store.state.products.forEach(product => {
product.price -= 1;
})
}
}
- 更改Vuex的store中的状态的唯一方法是提交mutation,Vuex中的mutation非常类似于事件,没个mutation都有一个字符串的事件类型[type]和一个回调函数,这个回调函数就是我们实际运行状态更改的地方,并且他会接受state作为第一个参数。
一般在触发事件时才使用mutation,如果是想要获取数据时就使用getters,想要存储数据时就用state,
//store.js
//触发事件,改变数据
mutations: {
reducePrice: state => {
state.products.forEach(product => {
product.price -= 1;
});
}
}
//在组件中使用时用commit激活事件,事件触发的事件名字要与store中的事件名字相同
methods: {
reducePrice() {
this.$store.commit("reducePrice");
}
}
vueX还兼容严格模式。
Actions
Actions提交的是mutation,而不是直接变更的数据状态。
如果实现异步操作应该在Action中实现。
Action是通过store.dispatch触发的。
//store/store.js
actions: {
reducePrice: context => {
setTimeout(() => {
context.commit("reducePrice");
}, 2000);
}
}
//组件中
methods: {
reducePrice() {
// this.$store.commit("reducePrice"); //此处commit是直接触发mutation中的方法
// 此处应调用actions里的方法
this.$store.dispatch("reducePrice"); //事件名对应store中actions中的方法名
}
}
- Actions 可以进行传参
组件方法中将参数写到分发事件后进行传递,store中通过payload参数进行接收。
//store.js
//触发事件,改变数据
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是直接触发mutation中的方法
// 此处应调用actions里的方法
this.$store.dispatch("reducePrice",amount); //事件名对应store中actions中的方法名
}
}
辅助函数
mapState
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。mapGetters
mapGetters辅助函数仅仅是将store中的getters映射到局部计算属性;mapMutations
使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用';mapActions
mapActions辅助函数将组件的methods映射为store.dispatch调用,需要先在根节点注入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"
})