当前位置: 首页 > article >正文

vue3前端开发-小兔鲜超市-本地购物车列表页面的统计计算

vue3前端开发-小兔鲜超市-本地购物车列表页面的统计计算!这一次,实现了一些本地购物车列表页面的,简单的计算。

代码如下所示:

import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
export const useCartStore =defineStore('cart',()=>{
    const cartList = ref([])
    const addCart = (goods)=>{
        //添加购物车操作
        //如果已经添加过了,count++
        //没有添加过,直接push
        //s思路:通过匹配传递过来的商品对象的中的skuId能不能在cartList中找到,
        const item = cartList.value.find((item)=>goods.skuId === item.skuId)
        if(item){
            //找到了
            item.count++
        }else{
            cartList.value.push(goods)
        }
    }
     // 删除购物车
    const delCart = async (skuId) => {
    // 思路:
    // 1. 找到要删除项的下标值 - splice
    // 2. 使用数组的过滤方法 - filter
    const idx = cartList.value.findIndex((item) => skuId === item.skuId)
    cartList.value.splice(idx, 1)
    }
    //单选功能
    const singleCheck=(skuId,selected)=>{
        const item = cartList.value.find((item)=>item.skuId===skuId)
        item.selected = selected
    }
    // 全选功能action
    const allCheck = (selected) => {
    // 把cartList中的每一项的selected都设置为当前的全选框状态
    cartList.value.forEach(item => item.selected = selected)
  }
    //计算属性的使用
    //1.总的数量
    const allCount =computed(()=>cartList.value.reduce((a,c)=>a+c.count,0))
    //2.总的货款
    const allPrice =computed(()=>cartList.value.reduce((a,c)=>a+c.count*c.price,0))
    //3.已经勾选的数量
    const selectedCount = computed(()=> cartList.value.filter(item => item.selected).reduce((a,c)=>a+c.count,0))
    //4.已选择商品的总货款
    const selectedPrice = computed(()=> cartList.value.filter(item => item.selected).reduce((a,c)=>a + c.count * c.price,0))

    // 是否全选计算属性
    const isAll = computed(() => cartList.value.every((item) => item.selected))
    return{
        cartList,
        addCart,
        delCart,
        allCheck,
        allCount,
        allPrice,
        selectedCount,
        selectedPrice,
        isAll,
        singleCheck
    }
},{
    //同步存储到缓存中,刷新浏览器就不会丢失数据了
    persist: true,
})

这个是store对象里面的增加了2个变量。分别是,当前选择的产品数量,当前勾选的产品的总货款。

如图所示。


<script setup>
import { useCartStore } from '@/stores/cart'
const cartStore = useCartStore()
// 单选回调
const singleCheck = (i, selected) => {
  console.log(i, selected)
  // store cartList 数组 无法知道要修改谁的选中状态?
  // 除了selected补充一个用来筛选的参数 - skuId
  cartStore.singleCheck(i.skuId, selected)
}
const allCheck = (selected) => {
  cartStore.allCheck(selected)
}
</script>

<template>
  <div class="xtx-cart-page">
    <div class="container m-top-20">
      <div class="cart">
        <table>
          <thead>
            <tr>
              <th width="120">
                
                <el-checkbox :model-value="cartStore.isAll" @change="allCheck"/>
              </th>
              <th width="400">商品信息</th>
              <th width="220">单价</th>
              <th width="180">数量</th>
              <th width="180">小计</th>
              <th width="140">操作</th>
            </tr>
          </thead>
          <!-- 商品列表 -->
          <tbody>
            <tr v-for="i in cartStore.cartList" :key="i.id">
              <td>
                <!--单选框-->
                <el-checkbox :model-value="i.selected" @change="(selected) => singleCheck(i, selected)"/>
              </td>
              <td>
                <div class="goods">
                  <RouterLink to="/"><img :src="i.picture" alt="" /></RouterLink>
                  <div>
                    <p class="name ellipsis">
                      {{ i.name }}
                    </p>
                  </div>
                </div>
              </td>
              <td class="tc">
                <p>&yen;{{ i.price }}</p>
              </td>
              <td class="tc">
                <el-input-number v-model="i.count" />
              </td>
              <td class="tc">
                <p class="f16 red">&yen;{{ (i.price * i.count).toFixed(2) }}</p>
              </td>
              <td class="tc">
                <p>
                  <el-popconfirm title="确认删除吗?" confirm-button-text="确认" cancel-button-text="取消" @confirm="delCart(i)">
                    <template #reference>
                      <a href="javascript:;">删除</a>
                    </template>
                  </el-popconfirm>
                </p>
              </td>
            </tr>
            <tr v-if="cartStore.cartList.length === 0">
              <td colspan="6">
                <div class="cart-none">
                  <el-empty description="购物车列表为空">
                    <el-button type="primary">随便逛逛</el-button>
                  </el-empty>
                </div>
              </td>
            </tr>
          </tbody>

        </table>
      </div>
      <!-- 操作栏 -->
      <div class="action">
        <div class="batch">
          共 {{ cartStore.allCount }} 件商品,已选择 {{cartStore.selectedCount}} 件,商品合计:
          <span class="red">¥ {{ cartStore.selectedPrice.toFixed(2) }} </span>
        </div>
        <div class="total">
          <el-button size="large" type="primary" >下单结算</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.xtx-cart-page {
  margin-top: 20px;

  .cart {
    background: #fff;
    color: #666;

    table {
      border-spacing: 0;
      border-collapse: collapse;
      line-height: 24px;

      th,
      td {
        padding: 10px;
        border-bottom: 1px solid #f5f5f5;

        &:first-child {
          text-align: left;
          padding-left: 30px;
          color: #999;
        }
      }

      th {
        font-size: 16px;
        font-weight: normal;
        line-height: 50px;
      }
    }
  }

  .cart-none {
    text-align: center;
    padding: 120px 0;
    background: #fff;

    p {
      color: #999;
      padding: 20px 0;
    }
  }

  .tc {
    text-align: center;

    a {
      color: $xtxColor;
    }

    .xtx-numbox {
      margin: 0 auto;
      width: 120px;
    }
  }

  .red {
    color: $priceColor;
  }

  .green {
    color: $xtxColor;
  }

  .f16 {
    font-size: 16px;
  }

  .goods {
    display: flex;
    align-items: center;

    img {
      width: 100px;
      height: 100px;
    }

    >div {
      width: 280px;
      font-size: 16px;
      padding-left: 10px;

      .attr {
        font-size: 14px;
        color: #999;
      }
    }
  }

  .action {
    display: flex;
    background: #fff;
    margin-top: 20px;
    height: 80px;
    align-items: center;
    font-size: 16px;
    justify-content: space-between;
    padding: 0 30px;

    .xtx-checkbox {
      color: #999;
    }

    .batch {
      a {
        margin-left: 20px;
      }
    }

    .red {
      font-size: 18px;
      margin-right: 20px;
      font-weight: bold;
    }
  }

  .tit {
    color: #666;
    font-size: 16px;
    font-weight: normal;
    line-height: 50px;
  }

}
</style>

 接下来就是在组件内,调用这个变量的值,做插值运算的调用就行了。

如图所示。这个位置改成了我们刚刚生成的数据信息。

登录用户,验证后操作显示一切正常。

 


http://www.kler.cn/news/309460.html

相关文章:

  • 新增的标准流程
  • Codeforces practice C++ 2024/9/11 - 2024/9/18
  • 常见数据湖的优劣对比
  • Rust表达一下中秋祝福,群发问候!
  • Spring Boot-依赖冲突问题
  • Verdin AM62 引脚复用配置
  • 检查和测绘室内防撞无人机技术详解
  • 机器学习的网络们
  • mysql 8.0 搭建主从集群注意事项
  • 从登录到免登录:JSP与Servlet结合Cookie的基本实现
  • react 组件通讯
  • 面试题篇: 跨域问题如何处理(Java和Nginx处理方式)
  • Linux 使用 tar 命令
  • C++掉血迷宫
  • 在vmvare安装飞牛私有云 fnOS体验教程
  • 自动化测试框架pytest命令参数
  • 如何在@GenericGenerator中显式指定schema
  • 友思特方案 | 搭建红外桥梁:嵌入式视觉接口助力红外热像仪传输
  • SpringBoot入门(黑马)
  • 【数据可视化】Arcgis api 4.x 专题图制作之分级色彩,采用自然间断法(使用simple-statistics JS数学统计库生成自然间断点)
  • 0072__ActiveX插件的使用
  • Linux云计算 |【第二阶段】SHELL-DAY5
  • pdf文件怎么转换成ppt?介绍几种pdf转ppt的方法
  • 传感技术的应用
  • 利用正则表达式匹配格式并且获取替换内容中数据并保留
  • VS+QT--实现二进制和十进制的转换(含分数部分)
  • 去中心化的力量:探索Web3的分布式网络
  • 工商银行银企直联接口清单
  • Java高级Day40-QQ项目全代码
  • 使用SQL数据构建问答系统的完整指南