一、需求
1、用户选择商品,自动回显在购物车列表中;
2、同个商品追加,购物车列表数量叠加;
3、开启赠送,选中的商品,在购物车中另增一条数据,且购物车列表价格显示为0;其实际价格在最后结算是优惠价格其值是`赠送数量*商品价格`;
4、页面刷新,之前添加的商品依然存在;重新选择商品,依然遵循同类商品数量叠加,新增商品追加在购物车最上面;
5、购物车手动叠加/减数量,在商品列表在选择商品可以实时更新;
6、购物车商品/赠品,单个移除;
7、清空购物车;
二、最终效果
三、实现逻辑
1、选择商品逻辑
1、获取本地缓存,查看是否存在购物车数据;
2、如果不存在——将点击选中的商品数据、排重且数量求和后、存到本地缓存中;
3、如果存在
1、判断购物车数据中是否存在现在要加购的商品(使用数组方法find)
2、存在该商品——将该商品的数量+1
3、不存在该商品——与已有商品一起加入到本地缓存中
2、初始化(即刷新后)----初始化获取本地缓存的数据
mounted() {
this.cacheHandler()
},
methods: {
// 获取缓存数据
cacheHandler() {
// 获取所有数据
if (localStorage.getItem('finallyCartList') && JSON.parse(localStorage.getItem('finallyCartList')).length > 0) {
this.finallyCartList = JSON.parse(localStorage.getItem('finallyCartList'))
this.shoppingCartActive = this.finallyCartList[0]
}
}
}
3、数量加减——用户增减商品数量,更新本地存储数据
4、删除——filter过滤已经删除的数据,更新本地存储数据
5、清空购物车——清空本地存储数据
6、选择商品关键代码:
// 选择商品
itemHandler(item) {
const cartObj = JSON.parse(JSON.stringify(item))
// 商品数量
cartObj.shoppingNum = 1
// 是否赠品
cartObj.isPresenter = this.isPresenter
// 配置购物车列表的唯一值
cartObj.soleId = `${cartObj.id}${cartObj.isPresenter}`
// 是否配送
cartObj.isDistribution = false
// 查看本地是否存在购物车数据
const store = JSON.parse(localStorage.getItem('finallyCartList') || '[]')
if (store.length > 0) {
// 判断购物车数据中是否存在现在要加购的商品
const currentInfo = store.find(el => {
return el.soleId == cartObj.soleId
})
if (currentInfo) {
// 存在数量叠加1
currentInfo.shoppingNum = currentInfo.shoppingNum + 1
this.finallyCartList = [...store]
} else {
// 不存在追加在购物车列表前面
this.finallyCartList = [cartObj, ...store]
}
} else {
/**
* 不存在本地购物车数据逻辑
*/
this.shoppingCartList.push(cartObj)
const shoppingCartList = JSON.parse(JSON.stringify(this.shoppingCartList))
// 排重且数量求和
const result = shoppingCartList.reduce((init, currentValue) => {
const leng = init.findIndex(cur => cur.soleId === currentValue.soleId)
if (leng != -1) {
init[leng].shoppingNum += currentValue.shoppingNum
} else {
init.push(currentValue)
}
return init
}, [])
this.finallyCartList = [...result]
}
// 把最终购物车列表数据缓存在本地
localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
// 购物车列表选中项
this.shoppingCartActive = this.finallyCartList[0]
// 初始化获取缓存数据
this.cacheHandler()
// console.log('finallyCartList', this.finallyCartList)
}
四、源码
export default {
name: 'Checkstand',
data() {
return {
shoppingCartList: [], // 购物车列表
finallyCartList: [], // 最终购物车列表
shoppingCartActive: {
shoppingNum: 1
}, // 购物车选中项
isPresenter: false, // 是否赠送
isDistribution: false // 是否配送
}
},
computed: {
// 优惠金额
discountsAmount() {
return this.finallyCartList.filter(val => val.isPresenter).reduce((retailPrice, currentStudent) => {
return retailPrice + (currentStudent.shoppingNum * currentStudent.retailPrice)
}, 0)
},
// 总金额
totalAmount() {
return this.finallyCartList.filter(val => !val.isPresenter).reduce((retailPrice, currentStudent) => {
return retailPrice + (currentStudent.shoppingNum * currentStudent.retailPrice)
}, 0)
}
},
mounted() {
this.cacheHandler()
},
methods: {
// 获取缓存数据
cacheHandler() {
// 获取所有数据
if (localStorage.getItem('finallyCartList') && JSON.parse(localStorage.getItem('finallyCartList')).length > 0) {
this.finallyCartList = JSON.parse(localStorage.getItem('finallyCartList'))
this.shoppingCartActive = this.finallyCartList[0]
}
},
// 点击购物车商品
activeHandler(item) {
this.shoppingCartActive = item
},
// 选择商品
itemHandler(item) {
const cartObj = JSON.parse(JSON.stringify(item))
// 商品数量
cartObj.shoppingNum = 1
// 是否赠品
cartObj.isPresenter = this.isPresenter
// 配置购物车列表的唯一值
cartObj.soleId = `${cartObj.id}${cartObj.isPresenter}`
// 是否配送
cartObj.isDistribution = false
// 查看本地是否存在购物车数据
const store = JSON.parse(localStorage.getItem('finallyCartList') || '[]')
if (store.length > 0) {
// 判断购物车数据中是否存在现在要加购的商品
const currentInfo = store.find(el => {
return el.soleId == cartObj.soleId
})
if (currentInfo) {
// 存在数量叠加1
currentInfo.shoppingNum = currentInfo.shoppingNum + 1
this.finallyCartList = [...store]
} else {
// 不存在追加在购物车列表前面
this.finallyCartList = [cartObj, ...store]
}
} else {
/**
* 不存在本地购物车数据逻辑
*/
this.shoppingCartList.push(cartObj)
const shoppingCartList = JSON.parse(JSON.stringify(this.shoppingCartList))
// 排重且数量求和
const result = shoppingCartList.reduce((init, currentValue) => {
const leng = init.findIndex(cur => cur.soleId === currentValue.soleId)
if (leng != -1) {
init[leng].shoppingNum += currentValue.shoppingNum
} else {
init.push(currentValue)
}
return init
}, [])
this.finallyCartList = [...result]
}
// 把最终购物车列表数据缓存在本地
localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
// 购物车列表选中项
this.shoppingCartActive = this.finallyCartList[0]
// 初始化获取缓存数据
this.cacheHandler()
// console.log('finallyCartList', this.finallyCartList)
},
// 清空购物车
clearCart() {
this.clearChche()
},
// 清空数据
clearChche() {
localStorage.setItem('finallyCartList', JSON.stringify([]))
localStorage.setItem('showMemberObj', JSON.stringify({}))
this.finallyCartList = []
this.shoppingCartActive = {
shoppingNum: 1
}
this.showMemberObj = { ticketCustomers: [] }
},
// 移除购物车商品
delCommodity() {
this.finallyCartList = this.finallyCartList.filter(val => this.shoppingCartActive.soleId !== val.soleId)
localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
this.shoppingCartActive = this.finallyCartList[0] || { shoppingNum: 1 }
this.cacheHandler()
},
// 配送选中事件
changeDistribution(val) {
if (!this.shoppingOrTicket) {
Toast('请先选择会员!')
return
}
this.finallyCartList.forEach(item => {
if (item.id === this.shoppingCartActive.id) {
item.isDistribution = val
}
})
localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
},
// 每次增减数量重置缓存
plusminusHandle() {
setTimeout(() => {
localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
}, 300)
},
// 收款
collection() {
console.log('会员信息', this.showMemberObj)
const params = {
addressId: this.showMemberObj.addressId || 0,
customerId: this.showMemberObj.customerId || 0,
customerPhone: this.showMemberObj.customerPhone || '',
address: this.showMemberObj.address || '',
customerName: this.showMemberObj.customerName || '',
operateType: 2,
directDiscountAmount: 0,
orderStatus: 0,
amountReceivable: this.totalAmount,
itemMessageDTOList: this.finallyCartList && this.finallyCartList.map(item => { return { itemCode: item.itemCode, qty: item.shoppingNum, itemGiftType: item.isPresenter ? 1 : 0, pickType: item.isDistribution ? 0 : 1 } })
}
console.log('收款最终参数--会员数据', params)
// return
this.$router.push({ path: '/settleAccounts', query: { data: JSON.stringify(params) } })
}
}
}
五、相关文章
Vue3 + Vite + Ts开源后台管理系统模板
基于ElementUi或AntdUI再次封装基础组件文档
基于Element-plus再次封装基础组件文档(vue3+ts)