vue之vuex实现购物车功能
vuex购物车vuex实现购物车的增删改查,单选,多选,反选,全选。 动态价格计算,数量统计。module模块化,namespaced命名空间state, actions, mutations,getters主要用法辅助函数,方法调用。
·
一、为什么用vuex来实现购物车功能
原本项目是没有完全用vuex来实现的,但购物车的一些公共状态,还有方法很混乱,最后为了开发维护使用方便就用了。购物车有很多实现方式,适合就好。
二、用到的vuex知识点。
- module模块化,namespaced命名空间
- state, actions, mutations,getters主要用法
- 辅助函数,方法调用。
vue之状态管理器vuex(三) 这是另外一篇的用法
三、store结构,主要文件用法。
- modules:按照功能划分的vuex模块,一般构建大些的项目时,条理更加清晰,便于维护开发。这里主要说 cart.js 购物车功能
- index.js : store的入口文件,各功能的继承。
- type.js : 定义方法常量,大写字母加下划线构成,可用可不用,根据情况。
- 在app.vue中引入挂载,上个文章里有,不多说。
- index.js (功能介绍都写在代码注释里吧)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//引入modules模块
import cart from './modules/cart.js'
//实例化vuex为store模块,挂载上cart,在下面导出,在app.vue引入挂载全局。
const store = new Vuex.Store({
modules: {
cart
}
})
export default store
- cart.js (购物车功能都在这里了)
代码中用到的一些uni-app接口方法,可根据实际情况替换。
// 引入请求数据接口的封装,每人实现和用法不一样。引入store,为了用一些方法。
import http from '@/common/request/index'
import store from '@/common/store'
// vuex方法常量的引入,让vuex的功能更细清晰,可用可不用,看需要。
import {
CART_LIST,
CART_NUM
} from '../types.js'
// vuex中state模块,定义当前功能用到的变量数据,类似data的初始化数据
// 页面调用:this.$store.state.cart.变量名
const state = {
cartList: [], //购物车数据。
allSelected: false, //购物车的全选状态。
cartNum: uni.getStorageSync('cartNum') ? uni.getStorageSync('cartNum') : '', //购物车,涉及到刷新数据丢失,所以存了本地,接口是uni.app框架的。
}
// vuex中actions模块,主要定义一些异步方法。
// 页面触发调用:this.$store.dispatch('方法名',参数只能有一个)
/**
*action和mutation都可以改变state中数据的状态,但是action可以处理异步函数可以在devtool中追 *踪数据变化,而mutation只可以处理同步函数,当处理异步函数的时候检测不到数据变化;
*/
const actions = {
// 购物车数据(查)
getCartList({
commit,
state
}) {
return new Promise((resolve, reject) => {
http('cartList').then(res => { //请求数据,无传参。
let cartData = res.data;
cartData.map(item => { // 重构购物车数据,加入选中状态,做单选多选用。
item.checked = false;
})
uni.setStorageSync('cartNum', cartData.length); //购物车数量
commit('CART_LIST', cartData); // 重构后的数据,提交给commit,触发数据更新。
commit('checkCartList'); // 每次请求购物车数据,做一次全选检测(全选时候加入新的购物车商品场景)
}).catch(e => {
reject(e)
})
})
},
// 添加到购物车(增)
addCartGoods({
commit
}, data) {
return new Promise((resolve, reject) => {
http('cartAdd', { // 添加购物车,传入商品id.
goodsId: data.id,
}).then(res => {
resolve(res)
store.dispatch('getCartList'); //更新购物车数。
}).catch(e => {
reject(e)
})
})
},
// 删除购物车商品(删)
changeCartList({
commit,
state,
dispatch
}, param) {
return new Promise((resolve, reject) => {
http('cartDelete', { // 删除购物车商品,传入ids;
cartIds: param.ids,
}).then(res => {
if (res.code === 1) {
dispatch('getCartList');//删除后,更新购物车。
}
}).catch(e => {
reject(e)
})
})
},
}
// vuex中mutations,主要用来触发数据更新,一些数据的同步操作。
// 页面分发调用:this.$store.commit('方法名',参数只能有一个)
const mutations = {
// cart数据获取变动。
[CART_LIST](state, data) {
state.cartList = data
},
// 切换全选。
changeAllSellect(state) {
state.allSelected = !state.allSelected;
},
// 全选设置,传入全选按钮的状态。
getAllSellectCartList(state, flag) {
state.cartList.map(item => {
item.checked = flag
})
},
// 单选设置,传入单选的商品下标,改变它的选中状态。
selectItem(
state, {
index,
flag
}) {
state.cartList[index].checked = !flag;
store.commit('checkCartList') // 每次单选,都要检测是否全部选中了。
},
// 全选检测
checkCartList(state) {
let all = true;
state.cartList.map(item => {
if (!item.checked) { // 枚举购物车数据,默认是全选,有一个没被选中,全选为false。
all = false
}
})
state.allSelected = all; // 更改全选状态。
}
}
//vuex中的getter,类似vue的computed计算属性,惰性动态监听计算数据,二次处理数据用。
// 页面调用:this.$store.getters.getters中的变量名(注意不是state中的)
const getters = {
// 购物车数量和总价
totalCount: state => {
let totalNum = 0;
let totalPrice = 0;
state.cartList.filter(item => {
if (item.checked) { // 筛选选中的商品,实时计算价格,数量。
totalNum += 1;
totalPrice += item.goods_num * item.sku_price.price;
}
})
return {
totalNum,
totalPrice
}
},
}
export default {
//namespaced:true,命名空间,防止方法污染,根据情况用。
state,
mutations,
actions,
getters
}
四、购物车页面的主要使用(部分代码)
// 引入vuex 辅助函数,上面每个模块在页面中的用法也可以,推荐辅助函数。
import { mapMutations, mapActions, mapState, mapGetters } from 'vuex';
export default
computed: {
...mapState({
cartList: ({ cart }) => cart.cartList,//在计算属性中获取vuex的数据,解构的cart模块,然后取值赋值。
allSel: ({ cart }) => cart.allSelected
}),
...mapGetters(['totalCount'])//直接拿getters中的处理过的数据。
},
created() {
this.getCartList();//获取页面数据。
},
methods: {
...mapActions(['getCartList', 'changeCartList']),//在这拿actions中的方法。
// 单选
onSel(index, flag) { //传入单选的下标,和选中状态,在vuex中接收。
let that = this;
that.$store.commit('selectItem', { index, flag });
},
// 全选
onAllSel() {
let that = this;
that.$store.commit('changeAllSellect'); //按钮切换全选。
that.$store.commit('getAllSellectCartList', that.allSel); //列表全选
},
// 删除
goodsDelete() {
let that = this;
let { cartList } = this;
let ids= [];
cartList.map(item => { //枚举出选中的商品,把id放入数组,传给vuex方法。
if (item.checked) {
ids.push(item.id);
}
});
this.changeCartList({ ids: ids });
}
}
};
基本就这些,有问题或者建议可以留言。
更多推荐
已为社区贡献5条内容
所有评论(0)