H5 shopping cart function achieves a milestone to commemorate 1024

First of all, I wish you all a happy holiday and no bugs!
Foreword: Back to the subject, the idea of ​​this article to realize the shopping cart is: get the back-end product list-front-end local cache added product data-get the data from the cache to render to the shopping cart page-get the data from the cache and submit the order. Therefore, it is mainly the storage, retrieval and removal of shopping cart data.

Product selection page

Insert picture description here
Analysis: Considering that the product list will be used in multiple places, and the operations to increase and decrease the number of products are the same, the list on the right is made into a component.

/*shopListRight.vue*/
<template>
  <div class="shopListRight">
    <div class="view-box">
      <i class="ifont i-logo"></i>
      <div class="view-box-item" v-for="(item,index) in listData" :key="index">
        <div class="img">
          <img v-if="item.imgPath" :src="item.imgPath">
          <img v-else src="../assets/images/img_bg.png">
        </div>
        <div class="con-right">
          <div class="con-right-title">{
    
    {
    
    item.goodsName}}</div>
          <div class="con-right-bottom">
            <div class="con-right-bottom-price">¥ {
    
    {
    
    item.price}}</div>
            <div class="con-right-botton-count">
              <img v-if="item.count" src="../assets/images/goods_reduce.png" @click="delCount(item)">
              <span v-if="item.count">{
    
    {
    
    item.count}}</span>
              <img src="../assets/images/goods_add.png" @click="addCount(item)">
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

Component style

.shopListRight {
    
    
  background: #fff;
}

.view-box-item {
    
    
  display: flex;
  margin-bottom: 2.03rem;
}
.view-box-item:last-of-type {
    
    
  margin-bottom: 0px;
}
.view-box-item > .img {
    
    
  width: 3.75rem;
  height: 3.75rem;
  margin-right: 0.9rem;
  background: #f6f6f7;
}
.view-box-item > .img > img {
    
    
  width: 100%;
  height: 100%;
}
.view-box-item .con-right {
    
    
  flex: 1;
  position: relative;
}
.view-box-item .con-right .con-right-title {
    
    
  font-size: 0.87rem;
  font-weight: bold;
  color: #333;
}
.view-box-item .con-right .con-right-bottom {
    
    
  position: absolute;
  width: 100%;
  bottom: -0.3rem;
  display: flex;
  justify-content: space-between;
}
.view-box-item .con-right .con-right-bottom .con-right-bottom-price {
    
    
  padding-top: 0.3rem;
  font-size: 0.75rem;
  font-weight: bold;
  color: #fe9900;
  vertical-align: middle;
}
.view-box-item .con-right .con-right-bottom .con-right-botton-count > span {
    
    
  vertical-align: middle;
  margin: 0 0.503rem;
}
.view-box-item .con-right .con-right-bottom .con-right-botton-count > img {
    
    
  width: 1.56rem;
  height: 1.56rem;
  vertical-align: middle;
}

Shopping cart logic processing

export default {
    
    
  data() {
    
    
    return {
    
    
      totalMoney: 0,
      totalNum: 0,
      carList: []
    }
  },
  props: {
    
    
    listData: {
    
    
      type: Array,
      default: () => []
    }
  },
  methods: {
    
    
    // 减数量
    delCount(item) {
    
    
      let carList = JSON.parse(localStorage.getItem('carList')) || []
      let index = carList.map(res => res.goodsId).indexOf(item.goodsId)
      if (index > -1 && carList[index].count > 0) {
    
    //购物车中已存在点击添加的商品
        carList[index].count--
      }
      let index2 = this.listData.map(item => item.goodsId).indexOf(item.goodsId)
      if (this.listData[index2].count > 0) {
    
    
        this.listData[index2].count--
        if (this.listData[index2].count == 0) {
    
    //减到数量为0时从购物车中移除该商品
          let index = carList.map(res => res.goodsId).indexOf(this.listData[index2].goodsId)
          carList.splice(index, 1)
        }
      }
      localStorage.setItem('carList', JSON.stringify(carList))
      this.$emit('initCarList')
      this.priceCount()
      this.numCount()
    },
    // 增加数量
    addCount(obj) {
    
    
      let item = obj
      let index2 = this.listData.map(res => res.goodsId).indexOf(item.goodsId)
      this.listData[index2].count++
      let carList = JSON.parse(localStorage.getItem('carList')) || []
      let index = carList.map(res => res.goodsId).indexOf(item.goodsId)
      if (index > -1) {
    
    //购物车中已存在点击添加的商品
        carList[index].count++
      } else {
    
    //购物车不存在点击的商品
        item.count = 1
        carList.push(item)
      }
      localStorage.setItem('carList', JSON.stringify(carList))
      this.priceCount()
      this.numCount()
    },
    // 计算总价
    priceCount() {
    
    
      let carList = JSON.parse(localStorage.getItem('carList')) || []
      let totalMoney = 0
      carList.map(res => {
    
    
        totalMoney += (res.price) * (res.count)
      })
      localStorage.setItem('totalMoney', totalMoney)
      this.$emit('getCountMoney', totalMoney)//向外传递数据
    },
    // 计算选购数量
    numCount() {
    
    
      let carList = JSON.parse(localStorage.getItem('carList')) || []
      let totalNum = 0
      carList.map(res => {
    
    
        totalNum += res.count
      })
      localStorage.setItem('totalNum', totalNum)
      this.$emit('getCountNum', totalNum)//向外传递数据
    }
  }
}

Use components on the page

<shopListRight :listData="listData" @getCountMoney="getCountMoney" @getCountNum="getCountNum"></shopListRight>

Page logic

data() {
    
    
  return {
    
    
    listData: [],//这是你需要渲染商品列表的数据
  }
},
methods:{
    
    
	//监听组件的事件、购物车数据变化时会将购物车的数量和对应的总金额传到页面中
	getCountMoney(value) {
    
    
      this.totalMoney = value.toFixed(2)
    },
    getCountNum(value) {
    
    
      this.totalNum = value
    }
}

Shopping cart page

Insert picture description here
Page code

<template>
  <div class="carlist">
    <div class="carlist-hand">
      <div class="carlist-hand-total">共计{
    
    {
    
    totalNum}}件商品</div>
      <div class="carlist-hand-right" @click="clearAll">
        <img src="../../assets/images/delete_icon.png">
        <span>清空购物车</span>
      </div>
    </div>
    <div class="scroll-div">
      <div class="scroll-div-con" v-if="carList.length">
        <shopListRight :listData="carList" @getCountMoney="getCountMoney" @getCountNum="getCountNum" @initCarList="initCarList"></shopListRight>
      </div>
      <div class="empty-data" v-else>
        <i class="empty-icon iconfont icon-caution"></i>
        <span>暂无数据</span>
      </div>
    </div>
    <div class="bottom-tab">
      <div class="flex-box">
        <div class="bottom-tab-box-price">¥{
    
    {
    
    totalMoney}}</div>
        <div class="bottom-tab-right" @click="goTosettlement">
          <div class="car-title">去结算</div>
        </div>
      </div>
    </div>
  </div>

</template>

Page logic

<script>
import {
    
     Dialog } from 'vant'
import shopListRight from "@/components/shopListRight"
export default {
    
    
  components: {
    
     shopListRight, [Dialog.Component.name]: Dialog.Component },
  data() {
    
    
    return {
    
    
      carList: [],
      totalMoney: 0,
      totalNum: 0,
      loading: true,
      storeId: '',
    }
  },
  activated() {
    
    

  },
  mounted() {
    
    
    this.initCarList()
    let query = this.$route.query
    this.storeId = query.storeId
    let totalMoney = localStorage.getItem('totalMoney') || 0
    this.totalMoney = Number(totalMoney).toFixed(2)
    this.totalNum = localStorage.getItem('totalNum') || 0
  },
  methods: {
    
    
    initCarList() {
    
    
      this.carList = JSON.parse(localStorage.getItem('carList')) || []
    },
    getCountMoney(value) {
    
    
      this.totalMoney = value.toFixed(2)
    },
    getCountNum(value) {
    
    
      this.totalNum = value
    },
    // 清空购物车
    clearAll() {
    
    
      Dialog.confirm({
    
    
        title: '提示',
        message: '请确认是否清空购物车所有商品?',
        confirmButtonText: '确认',
        confirmButtonColor: '#999',
        cancelButtonText: '我再想想',
        cancelButtonColor: '#ff6600'
      }).then(() => {
    
    
        this.carList = []
        this.totalNum = 0
        this.totalMoney = 0
        localStorage.setItem('listData', [])
        localStorage.setItem('carList', [])
        localStorage.setItem('totalNum', 0)
        localStorage.setItem('totalMoney', 0)
      })
    },
    // 去结算
    goTosettlement() {
    
    
      this.$router.push({
    
     path: './confirmOrder', query: {
    
     isSettlement: true, storeId: this.storeId } })
    },
  },
}
</script>

The final cache is like this:
Insert picture description here
totalNum: records the selected number of
shopping carts
carList: records all product information added to the shopping cart totalMoney: records the price of all products in the shopping cart
listData: component rendering data

See effect

Insert picture description here

Insert picture description here
Insert picture description here
The above is all that h5 implements the shopping cart function. See you in the comment area if you have any questions!

Guess you like

Origin blog.csdn.net/Smell_rookie/article/details/109119692