请先参考另一篇文章VUE兄弟组件传参
当一个应用中数据过多时,我们将数据都写在store中显得代码过长,不利于代码复用,所以我们将代码分块
即store实例中有state,mutations,actions,getters,state中又有一个product,product中又有state,mutations,actions,getters,则数据进行了分级,所以采用代码分块,将product写在modules中,再写一个product.js模块,引入这个模块就可以了
import Vue from "vue";
import Vuex from "vuex";
import product from "./modules/product";
import movie from "./modules/movie";
import cart from "./modules/shopcart";
Vue.use(Vuex);
//建立一个vuex实例,vuex用来解决跨组件传参
//$store.state.count可以表示vuex中的数据
const store = new Vuex.Store({
state: {
count: 1,
title: "我是一个计数器",
},
//同步操作
mutations: {
//payload载荷(传递的数据)
plus(state, payload) {
console.log(payload);
state.count++;
},
},
//异步操作
actions: {
//context存储的是上下文数据store的值
//参数二表示传递的数据
asyncPlus(context, payload) {
setTimeout(function() {
console.log(context);
console.log(payload);
//const { commit } = context;
//commit("plus", { step: 2 }); //提交一个mutation
//既然context是获取的上下文store的值,那么可不可以直接在actions中操作,不再到mutations中操作
const { commit, state } = context;
state.count++;
//这种方法是可以的,但是devtools追踪不到数据的变化
}, 3000);
},
},
getters: {
currentState(state) {
return "当前的state为:" + state.count;
},
},
modules: {
product,
movie,
cart,
},
});
export default store;
product.js代码
import { pagedProducts } from "../../services/product";
const product = {
namespaced: true, //启用命名空间,每一个模块在定义的时候都需要设置namespaced为true,这样在其他组件中使用这个vuex中的数据时才可以使用,使用时需要先写这个模块的名字
state: {
list: [], //列表
page: 1, //页码
per: 10, //每一页显示的数量
},
actions: {
//加载数据
async loadData({ commit }, payload) {
//此处可以做异步操作
//调接口请求数据,然后调用save方法
const result = await pagedProducts(payload);
commit("save", result.data); //axios请求的数据放在返回数据的data属性中
},
},
mutations: {
save(state, payload) {
//改变数据
//state.list = state.list.concat(payload.products);
state.list = [...state.list, ...payload.products];
state.page += 1;
},
},
};
export default product;
movie.js代码
const movie = {
namespaced: true, //启用命名空间,每一个模块在定义的时候都需要设置namespaced为true
state: {
list: [],
},
};
export default movie;
比如在product.vue组件中需要使用vuex中的数据,代码如下
<template>
<div class="list">
<van-card
num="2"
:price="item.price"
:desc="item.descriptions"
:title="item.name"
:thumb="item.coverImg"
v-for="item in list"
:key="item.id"
>
<div slot="tags">
<van-tag plain type="danger">标签</van-tag>
<van-tag plain type="danger">标签</van-tag>
</div>
<div slot="footer">
<van-button size="mini">按钮</van-button>
<van-button type="danger" size="mini" @click="buyHandle(item._id)">购买</van-button>
</div>
</van-card>
<button @click="loadMore">load more...</button>
</div>
</template>
<script>
import { mapState, mapActions, mapMutations } from "vuex";
export default {
created() {
//当前没有数据时才会请求数据,否则点击一次热卖就加载一次数据,而不仅仅是点击load more才加载数据
if (this.list.length == 0) {
this.loadData();
}
},
computed: {
//第一个参数表示命名空间,因为分模块了,第二个参数表示将模块的state映射到此组件
...mapState("product", {
//获取product模块的数据在当前组件显示
list: "list",
page: "page",
per: "per"
})
},
methods: {
...mapActions("product", {
loadData: "loadData"
}),
...mapMutations("cart", ["addToCart"]),
loadMore() {
console.log("page");
this.loadData({
page: this.page
});
},
buyHandle(id) {
this.addToCart({
id,
amount: 1
});
}
}
};
</script>