Vue3电商项目实战-购物车模块5【12-购物车页面-批量删除-本地、13-购物车页面-无效商品-本地、14-购物车页面-修改数量-本地、15-购物车页面-修改规格-本地】

本文详细介绍了在本地实现购物车页面的各种功能,包括批量删除选中和失效商品、修改商品数量以及修改商品规格。通过Vue.js和Vuex,实现了批量删除的actions和mutations,以及商品数量的更新。此外,还封装了一个购物车SKU组件用于展示和修改商品规格。
摘要由CSDN通过智能技术生成


12-购物车页面-批量删除-本地

目的:实现本地批量删除选中商品功能。

大致的步骤:

  • 定义一个批量删除商品的actions支持批量操作
  • 遍历选中商品,调用单个删除调用mutations函数即可
  • 绑定批量删除点击事件指定处理函数,调用actions进行删除。

落地代码:

  • 批量操作商品的actions支持 src/store/module/cart.js
    // 批量删除选中商品
    batchDeleteCart (ctx) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 登录 TODO
        } else {
          // 本地
          // 1. 获取选中商品列表,进行遍历调用deleteCart mutataions函数
          ctx.getters.selectedList.forEach(item => {
            ctx.commit('deleteCart', item.skuId)
          })
          resolve()
        }
      })
    },
  • 绑定批量删除点击事件指定处理函数,调用actions进行删除。 src/views/cart/index.vue
<a @click="batchDeleteCart()" href="javascript:;">删除商品</a>
    // 批量删除
    const batchDeleteCart = () => {
      Confirm({ text: '您确定从购物车删除选中的商品吗?' }).then(() => {
        store.dispatch('cart/batchDeleteCart')
      }).catch(e => {})
    }
    return { checkOne, checkAll, deleteCart, batchDeleteCart }

13-购物车页面-无效商品-本地

目的:实现本地清空无效商品功能。

大致思路:

  • 去修改批量删除的actions让它适用于两个场景
    • 批量删除选中的
    • 批量删除失效的 isClear

落地代码:

  • 绑定清空无效商品点击事件指定处理函数,调用actions进行删除。 src/views/cart/index.vue
<a @click="batchDeleteCart(true)" href="javascript:;">清空失效商品</a>
    // 批量删除
+    const batchDeleteCart = (isClear) => {
+      Confirm({ text: `您确定从购物车删除${isClear ? '失效' : '选中'}的商品吗?` }).then(() => {
        store.dispatch('cart/batchDeleteCart', isClear)
      }).catch(e => {})
    }
    return { checkOne, checkAll, deleteCart, batchDeleteSelectedCart, batchDeleteInvalidCart }
  • 批量删除商品的actions支持清空无效 src/store/module/cart.js
    // 批量删除选中商品
+    batchDeleteCart (ctx, isClear) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 登录 TODO
        } else {
          // 本地
          // 1. 获取选中商品列表,进行遍历调用deleteCart mutataions函数
+          ctx.getters[isClear ? 'invalidList' : 'selectedList'].forEach(item => {
            ctx.commit('deleteCart', item.skuId)
          })
          resolve()
        }
      })
    },

14-购物车页面-修改数量-本地

目的:实现本地版本的修改商品数量。

大致的步骤:

  • 绑定xtx-numbox组件的change事件指定处理函数
  • 在函数种调用vuex的cart/updateCart函数修改数量

落的代码:

  • 绑定xtx-numbox组件的change事件指定处理函数
<XtxNumbox :max="item.stock" @change="$event=>changeCount(item.skuId,$event)" :modelValue="item.count" />
  • 在函数种调用vuex的cart/updateCart函数修改数量
    // 修改数量
    const changeCount = (skuId, count) => {
      store.dispatch('cart/updateCart', { skuId, count })
    }
    return { checkOne, checkAll, deleteCart, batchDeleteCart, changeCount }

15-购物车页面-修改规格-本地

目的:封装一个购物车SKU组件,来修改规格。

在这里插入图片描述

大致步骤:

  • 定义一个组件完成基础结构
  • 完成展开收起操作
  • 展开的时候根据skuId得到商品信息(specs,skus)渲染商品规格。
  • 选择完毕后,点击确认后,修改当前商品规格。

落的代码:

  • 1.定义一个组件完成基础结构
    定义组件 src/views/cart/components/cart-sku.vue
<template>
  <div class="cart-sku">
    <div class="attrs">
      <span class="ellipsis">颜色:粉色 尺寸:14cm 产地:中国</span>
      <i class="iconfont icon-angle-down"></i>
    </div>
    <div class="layer">
      <div class="loading"></div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'CartSku'
}
</script>
<style scoped lang="less">
.cart-sku {
  height: 28px;
  border: 1px solid #f5f5f5;
  padding: 0 6px;
  position: relative;
  margin-top: 10px;
  display:inline-block;
  .attrs {
    line-height: 24px;
    display: flex;
    span {
      max-width: 230px;
      font-size: 14px;
      color: #999;
    }
    i {
      margin-left: 5px;
      font-size: 14px;
    }
  }
  .layer {
    position: absolute;
    left: -1px;
    top: 40px;
    z-index: 10;
    width: 400px;
    border: 1px solid @xtxColor;
    box-shadow: 2px 2px 4px lighten(@xtxColor,50%);
    background: #fff;
    border-radius: 4px;
    font-size: 14px;
    padding: 20px;
    &::before {
      content: "";
      width: 12px;
      height: 12px;
      border-left: 1px solid @xtxColor;
      border-top: 1px solid @xtxColor;
      position: absolute;
      left: 12px;
      top: -8px;
      background: #fff;
      transform: scale(.8,1) rotate(45deg);
    }
    .loading {
      height: 224px;
      background: url(../../../assets/images/loading.gif) no-repeat center;
    }
  }
}
</style>

使用组件 src/views/cart/index.vue

+import CartSku from './components/cart-sku'
export default {
  name: 'XtxCartPage',
+  components: { GoodRelevant, CartNone, CartSku },
                  <div>
                    <p class="name ellipsis">{{item.name}}</p>
                    <!-- 选择规格组件 -->
+                    <CartSku />
                  </div>
  • 2.完成展开收起操作 src/views/cart/components/cart-sku.vue
  <div class="cart-sku" ref="target">
    <div class="attrs" @click="toggle()">
      <span class="ellipsis">{{attrsText}}</span>
<script>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
export default {
  name: 'CartSku',
  props: {
    attrsText: {
      type: String,
      default: ''
    }
  },
  setup (props) {
    const visible = ref(false)
    const goods = ref(null)
    const show = () => {
      visible.value = true
    }
    const hide = () => {
      visible.value = false
    }
    const toggle = () => {
      visible.value ? hide() : show()
    }
    const target = ref(null)
    onClickOutside(target, () => {
      hide()
    })
    return { visible, toggle, target, goods }
  }
}
</script>
  • 3.展开的时候根据skuId得到商品信息(specs,skus)渲染商品规格。

接口API src/api/goods.js

/**
 * 获取商品的specs和skus
 * @param {String} skuId - 商品SKUID
 * @returns Promise
 */
export const getSpecsAndSkus = (skuId) => {
  return request(`/goods/sku/${skuId}`, 'get')
}

使用组件传人skuId src/views/cart/index.vue

                  <div>
                    <p class="name ellipsis">{{item.name}}</p>
                    <!-- 选择规格组件 -->
+                    <CartSku attrs-text="item.attrsText" :skuId="item.skuId" />
                  </div>

,
    skuId: {
      type: String,
      default: ''
    }

请求数据渲染 src/views/cart/components/cart-sku.vue

    <div class="layer" v-if="visible">
      <div v-if="!goods" class="loading"></div>
      <GoodsSku v-if="goods" :skuId="skuId" :goods="goods" />
      <XtxButton v-if="goods" type="primary" size="mini" style="margin-left:60px">确认</XtxButton>
    </div>
+    const goods = ref(null)
    const show = () => {
      visible.value = true
+      // 获取当前spec和sku数据
+      getSpecsAndSkus(props.skuId).then(data => {
+        goods.value = data.result
+      })
    }
    const hide = () => {
      visible.value = false
+      goods.value = null
    }
  • 4.选择完毕后,点击确认后,修改当前商品规格。
    在这里插入图片描述

cart-sku.vue组件确认后传出sku信息

    // 选择SKU时候触发
    const currSku = ref(null)
    const changeSku = (sku) => {
      currSku.value = sku
    }
    // 点击确认的时候,提交sku信息给购物车组件
    const submit = () => {
      // 给购物车组件数据的前提:有sku信息,sku信息完整,sku中的skuId不能现有props.skuId一样
      if (currSku.value && currSku.value.skuId && currSku.value.skuId !== props.skuId) {
        emit('change', currSku.value)
        hide()
      }
    }
    return { visible, toggle, target, goods, changeSku, submit }
<XtxButton v-if="goods" size="mini" type="primary" @click="submit()">确认</XtxButton>
<GoodsSku @change="changeSku" v-if="goods" :skuId="skuId" :goods="goods" />

cart/index.vue组件给cark-sku.vue组件绑定change事件,传入默认值和当前的商品信息。

                    <!-- 选择规格组件 -->
<CartSku @change="$event=>updateCartSku(item.skuId,$event)"
     // 修改规格
    const updateCartSku = (oldSkuId, newSku) => {
      store.dispatch('cart/updateCartSku', { oldSkuId, newSku })
    }
    return { checkOne, checkAll, deleteCart, batchDeleteCart, changeCount, updateCartSku }

再在actions种实现逻辑 src/store/modules/cart.js

    // 修改sku规格函数
    updateCartSku (ctx, { oldSkuId, newSku }) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 登录 TODO
        } else {
          // 本地
          // 但你修改了sku的时候其实skuId需要更改,相当于把原来的信息移出,创建一条新的商品信息。
          // 1. 获取旧的商品信息
          const oldGoods = ctx.state.list.find(item => item.skuId === oldSkuId)
          // 2. 删除旧的商品
          ctx.commit('deleteCart', oldSkuId)
          // 3. 合并一条新的商品信息
          const { skuId, price: nowPrice, inventory: stock, specsText: attrsText } = newSku
          const newGoods = { ...oldGoods, skuId, nowPrice, stock, attrsText }
          // 4. 去插入即可
          ctx.commit('insertCart', newGoods)
        }
      })
    },
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值