老师 还是上次提过的问题,在店铺里添加到了购物车,在我的购物车中数据获取的问题,按照老师的代码进行了修改,但是问题还是有点多
1、没有显示所有店铺的购物车数据
2、全选按钮有问题
3、总计价格有问题
cartList.vue页面:
<template>
<div class="wrapper">
<div class="title">我的全部购物车</div>
<div v-for="(shopItem, shopId) in cartList"
:key="shopId">
<div class="cart">
<div class="cart__title">
{{shopItem.shopName}}
</div>
<div class="cart__wrapper">
<div class="product__list">
<div v-for="item in shopItem.productList"
:key="item.id"
class="product__item">
<div class="product__item__checked iconfont"
v-html="item.check ? '': ''"
@click="() => changeCartItemChecked(shopId, item.id)" />
<img class="product__item__img"
:src="item.imgUrl" />
<div class="product__item__detail">
<h4 class="product__item__title">{{item.name}}</h4>
<p class="product__item__price">
<span class="product__item__yen">¥</span>{{item.price}}
<!-- <span class="product__item__origin">¥{{item.oldPrice}}</span> -->
</p>
</div>
<div class="product__number">
<span class="product__number__minus iconfont"
@click="() => { changeCartItemInfo(shopId, item.id, item, -1) }"></span>
<span class="product__number__value">{{item.count || 0}}</span>
<span class="product__number__plus iconfont"
@click="() => { changeCartItemInfo(shopId, item.id, item, 1) }"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="check">
<div class="check__all"
@click="() => setCartItemsChecked(shopId)">
<span class="check__all__icon iconfont"
v-html="calculations.allChecked ? '': ''">
</span>
全选
</div>
<div class="check__info">
总计:<span class="check__info__price">¥ {{calculations.price}}</span>
</div>
<div class="check__btn"
v-show="calculations.total > 0">
<!-- 跳转到提交订单页面 -->
<router-link :to="{path: `/orderConfirmation/${shopId}`}">
去结算
</router-link>
</div>
</div>
</div>
<Docker :currentIndex="1" />
</template>
<script>
import Docker from '../../components/Docker'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
import { useCommonCartEffect } from '../../effects/cartEffects'
// 获取购物车信息逻辑
const useCartEffect = (shopId) => {
const store = useStore()
const cartList = store.state.cartList
// 操作购物车的功能是类似的
const changeCartItemInfo = (shopId, productId, productInfo, num) => {
store.commit('changeCartItemInfo', {
shopId, productId, productInfo, num
})
}
const { calculations } = useCommonCartEffect(shopId)
const changeCartItemChecked = (shopId, productId) => {
store.commit('changeCartItemChecked', { shopId, productId })
}
const setCartItemsChecked = (shopId) => {
// 如果全选状态,点击按钮后取消全选,如果非全选状态,点击按钮后全部选中
const allChecked = !calculations.value.allChecked
store.commit('setCartItemsChecked', { shopId, allChecked })
}
return {
cartList, calculations, changeCartItemInfo, changeCartItemChecked, setCartItemsChecked
}
}
export default {
name: 'CartList',
components: { Docker },
setup () {
const route = useRoute()
const shopId = route.params.id
const {
cartList, calculations, changeCartItemInfo, changeCartItemChecked, setCartItemsChecked
} = useCartEffect(shopId)
return {
cartList, calculations, changeCartItemInfo, changeCartItemChecked, setCartItemsChecked
}
}
}
</script>
<style lang="scss" scoped>
@import "../../style/viriables.scss";
@import "../../style/mixins.scss";
.wrapper {
overflow-y: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0.5rem;
right: 0;
background: #f8f8f8;
}
.title {
line-height: 0.44rem;
background: $bgColor;
font-size: 0.16rem;
color: $content-fontcolor;
text-align: center;
}
.cart {
margin: 0.16rem 0.18rem 0.1rem 0.18rem;
background: $bgColor;
border-radius: 0.04rem 0.04rem 0 0;
&__title {
padding: 0.16rem;
font-size: 0.16rem;
color: $content-fontcolor;
}
&__wrapper {
overflow-y: scroll;
margin: 0 0.18rem;
position: absolute;
left: 0;
right: 0;
top: 1.1rem;
}
}
.product {
&__list {
background: $bgColor;
border-radius: 0 0 0.04rem 0.04rem;
}
&__item {
position: relative;
display: flex;
padding: 0.12rem 0;
margin: 0 0.18rem;
border-bottom: 0.01rem solid $content-bgColor;
&__checked {
line-height: 0.5rem;
margin-right: 0.2rem;
color: $btn-bgColor;
font-size: 0.2rem;
}
&__detail {
overflow: hidden;
}
&__img {
width: 0.46rem;
height: 0.46rem;
margin-right: 0.16rem;
}
&__title {
margin: 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $content-fontcolor;
@include ellipsis;
}
&__price {
margin: 0.06rem 0 0 0;
line-height: 0.2rem;
font-size: 0.14rem;
color: $hightlight-fontColor;
}
&__yen {
font-size: 0.12rem;
}
&__origin {
margin-left: 0.06rem;
line-height: 0.2rem;
font-size: 0.12rem;
color: $light-fontColor;
text-decoration: line-through;
}
.product__number {
position: absolute;
right: 0;
bottom: 0.26rem;
&__minus {
position: relative;
top: 0.02rem;
color: $medium-fontColor;
margin-right: 0.05rem;
font-size: 0.2rem;
}
&__plus {
position: relative;
top: 0.02rem;
color: $btn-bgColor;
margin-left: 0.05rem;
font-size: 0.2rem;
}
&__value {
font-size: 0.13rem;
}
}
}
}
.check {
width: 100%;
position: absolute;
bottom: 0;
display: flex;
height: 0.49rem;
background-color: $bgColor;
border-top: 0.01rem solid $content-bgColor;
line-height: 0.49rem;
&__all {
width: 0.64rem;
margin-left: 0.18rem;
font-size: 0.12rem;
&__icon {
display: inline-block;
margin-right: 0.05rem;
vertical-align: top;
color: $btn-bgColor;
font-size: 0.2rem;
}
}
&__info {
flex: 1;
color: $content-fontcolor;
font-size: 0.12rem;
text-align: right;
line-height: 0.49rem;
margin-right: 0.18rem;
&__price {
line-height: 0.49rem;
color: $hightlight-fontColor;
font-size: 0.18rem;
}
}
&__btn {
width: 0.98rem;
background-color: #4fb0f9;
text-align: center;
font-size: 0.14rem;
margin-left: 0.2rem;
a {
color: $bgColor;
text-decoration: none;
}
}
}
</style>
===============================
store -> index.js页面
import Vuex from 'vuex'
import { post } from '../utils/request'
// 给cartList数据做持久存储
const setLocalCartList = (state) => {
const { cartList } = state
const cartListString = JSON.stringify(cartList)
localStorage.cartList = cartListString
}
const getLocalCartList = () => {
// { shopId: {shopName:'', productList:{ productId: {} }}}
try {
return JSON.parse(localStorage.cartList)
} catch (e) {
return {}
}
}
export default Vuex.createStore({
state: {
cartList: getLocalCartList(),
userId: ''
},
mutations: {
saveUserId (state, payload) {
state.userId = payload.userId
},
changeCartItemInfo (state, payload) {
const { shopId, productId, productInfo } = payload
const shopInfo = state.cartList[shopId] || {
shopName: '', productList: {}
}
let product = shopInfo.productList[productId]
if (!product) {
productInfo.count = 0
product = productInfo
}
product.count = product.count + payload.num
if (payload.num > 0) { product.check = true }
if (product.count < 0) { product.count = 0 }
shopInfo.productList[productId] = product
state.cartList[shopId] = shopInfo
console.log('cart state:', state)
console.log('userId:', state.userId, 'shopId:', shopId, 'goodsId:', product.id, 'goodsNum:', product.count, 'goodsName:', product.goodsName, 'img:', product.imgUrl)
// 加入购物车
const addCart = async () => {
try {
const result = await post('/cart/create', {
shopId: shopId,
goodsId: product.id,
goodsNum: product.count,
goodsName: product.goodsName,
img: product.imgUrl
})
if (result?.code === 1) {
console.log('添加购物车成功')
} else {
console.log('添加购物车失败')
}
} catch (e) {
console.log('请求失败')
}
}
addCart()
setLocalCartList(state)
},
changeShopName (state, payload) {
const { shopId, shopName } = payload
const shopInfo = state.cartList[shopId] || {
shopName: '', productList: {}
}
shopInfo.shopName = shopName
state.cartList[shopId] = shopInfo
setLocalCartList(state)
},
changeCartItemChecked (state, payload) {
const { shopId, productId } = payload
const product = state.cartList[shopId].productList[productId]
product.check = !product.check
setLocalCartList(state)
},
cleanCartProducts (state, payload) {
const { shopId } = payload
state.cartList[shopId].productList = {}
setLocalCartList(state)
},
setCartItemsChecked (state, payload) {
// 接收allChecked
const { shopId, allChecked } = payload
const products = state.cartList[shopId].productList
if (products) {
for (const key in products) {
const product = products[key]
// 如果allChecked值为true,将每个商品的check值设为true
if (allChecked) {
product.check = true
} else {
// 如果allChecked值为false,将每个商品的check值设为false
product.check = false
}
}
}
setLocalCartList(state)
},
clearCartData (state, shopId) {
state.cartList[shopId].productList = {}
}
}
})
正在回答
同学你好,同学的数据和讲师的数据有区别,所以渲染时,要注意数据名称问题。老师简单修改了cartList页面,效果应该符合同学的要求了,请查看(结构和样式都有调整):
<template> <div class="wrapper"> <div class="title">我的全部购物车</div> <!-- 遍历全部购物车数据,并渲染;shopId就是商店id --> <div v-for="(shopItem, shopId) in cartList" :key="shopId"> <div class="cart"> <div class="cart__title"> {{ shopItem.shopName }} </div> <div class="cart__wrapper"> <div class="product__list"> <!-- 遍历数据,只显示count>0的 --> <template v-for="item in shopItem.productList" :key="item._id"> <div v-if="item.count >0" class="product__item"> <div class="product__item__checked iconfont" v-html="item.check ? '' : ''" @click="() => changeCartItemChecked(shopId, item.id)" /> <img class="product__item__img" :src="item.imgUrl" /> <div class="product__item__detail"> <h4 class="product__item__title">{{ item.name }}</h4> <p class="product__item__price"> <span class="product__item__yen">¥</span >{{ item.price }} <!-- <span class="product__item__origin">¥{{item.oldPrice}}</span> --> </p> </div> <div class="product__number"> <span class="product__number__minus iconfont" @click=" () => { changeCartItemInfo(shopId, item.id, item, -1) } " ></span > <span class="product__number__value">{{ item.count || 0 }}</span> <span class="product__number__plus iconfont" @click=" () => { changeCartItemInfo(shopId, item.id, item, 1) } " ></span > </div> </div> </template> </div> </div> </div> </div> </div> <Docker :currentIndex="1" /> </template> <script> import Docker from '../../components/Docker' import { useStore } from 'vuex' // 获取购物车信息逻辑 const useCartEffect = () => { // 获取全部购物车数据 const store = useStore() const cartList = store.state.cartList // 操作购物车的功能是类似的 const changeCartItemInfo = (shopId, productId, productInfo, num) => { store.commit('changeCartItemInfo', { shopId, productId, productInfo, num }) } const changeCartItemChecked = (shopId, productId) => { store.commit('changeCartItemChecked', { shopId, productId }) } const setCartItemsChecked = (shopId) => { store.commit('setCartItemsChecked', { shopId }) } return { cartList, changeCartItemInfo, changeCartItemChecked, setCartItemsChecked } } export default { name: 'CartList', components: { Docker }, setup () { const { changeCartItemInfo, changeCartItemChecked, setCartItemsChecked, cartList } = useCartEffect() return { cartList, changeCartItemInfo, changeCartItemChecked, setCartItemsChecked } } } </script> <style lang="scss" scoped> @import '../../style/viriables.scss'; @import '../../style/mixins.scss'; .wrapper { overflow-y: auto; position: absolute; left: 0; top: 0; bottom: 0.5rem; right: 0; background: #f8f8f8; } .title { line-height: 0.44rem; background: $bgColor; font-size: 0.16rem; color: $content-fontcolor; text-align: center; } .cart { margin: 0.16rem 0.18rem 0.1rem 0.18rem; background: $bgColor; border-radius: 0.04rem 0.04rem 0 0; &__title { padding: 0.16rem; font-size: 0.16rem; color: $content-fontcolor; } &__wrapper { overflow-y: scroll; margin: 0 0.18rem; // 这里做了修改 // position: absolute; // left: 0; // right: 0; // top: 1.1rem; } } .product { &__list { background: $bgColor; border-radius: 0 0 0.04rem 0.04rem; } &__item { position: relative; display: flex; padding: 0.12rem 0; margin: 0 0.18rem; border-bottom: 0.01rem solid $content-bgColor; &__checked { line-height: 0.5rem; margin-right: 0.2rem; color: $btn-bgColor; font-size: 0.2rem; } &__detail { overflow: hidden; } &__img { width: 0.46rem; height: 0.46rem; margin-right: 0.16rem; } &__title { margin: 0; line-height: 0.2rem; font-size: 0.14rem; color: $content-fontcolor; @include ellipsis; } &__price { margin: 0.06rem 0 0 0; line-height: 0.2rem; font-size: 0.14rem; color: $hightlight-fontColor; } &__yen { font-size: 0.12rem; } &__origin { margin-left: 0.06rem; line-height: 0.2rem; font-size: 0.12rem; color: $light-fontColor; text-decoration: line-through; } .product__number { position: absolute; right: 0; bottom: 0.26rem; &__minus { position: relative; top: 0.02rem; color: $medium-fontColor; margin-right: 0.05rem; font-size: 0.2rem; } &__plus { position: relative; top: 0.02rem; color: $btn-bgColor; margin-left: 0.05rem; font-size: 0.2rem; } &__value { font-size: 0.13rem; } } } } .check { width: 100%; position: absolute; bottom: 0; display: flex; height: 0.49rem; background-color: $bgColor; border-top: 0.01rem solid $content-bgColor; line-height: 0.49rem; &__all { width: 0.64rem; margin-left: 0.18rem; font-size: 0.12rem; &__icon { display: inline-block; margin-right: 0.05rem; vertical-align: top; color: $btn-bgColor; font-size: 0.2rem; } } &__info { flex: 1; color: $content-fontcolor; font-size: 0.12rem; text-align: right; line-height: 0.49rem; margin-right: 0.18rem; &__price { line-height: 0.49rem; color: $hightlight-fontColor; font-size: 0.18rem; } } &__btn { width: 0.98rem; background-color: #4fb0f9; text-align: center; font-size: 0.14rem; margin-left: 0.2rem; a { color: $bgColor; text-decoration: none; } } } </style>
效果:
至于底部的计算,同学参考其他购物车逻辑,自己计算一下。
祝学习愉快!
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星