Vue项目商品购物车前端本地缓存逻辑(适用H5/ipad/PC端)——前端实现购物车删除商品、购物车增减数量,清空购物车功能、新增扫码枪扫码添加到购物车功能

新增扫码枪扫码添加到购物车功能且购物车选中状态根据扫码商品自动选中

export default {
  data() {
    return {
      shoppingCartActive: {
        shoppingNum: 1
      }, // 购物车选中项
      scanValue: '', // 扫码枪返回的code
      timer: null // 监听扫码枪循环
    }
  },
  mounted() {
    this.cacheHandler()
    // 监听扫码抢
    this.onScan()
  },
  beforeDestroy() {
    clearInterval(this.timer)
  },
  methods: {
    // 根据扫码code码获取数据
    async getItemDetails(productSn) {
      // console.log('scanValue---', this.scanValue)
      const res = await this.$api.getItemDetails({ productSn })
      if (res.success) {
        // console.log('获取详情数据', res.data)
        this.itemHandler(res.data)
      }
    },
    // 扫码枪
    onScan() {
      const _this = this
      this.timerKey = new Date().getTime()
      // 获取扫码枪参数
      this.scanValue = ''
      this.setteim = new Date().getTime()
      this.timer = setInterval(() => {
        if (new Date().getTime() - this.setteim > 200) {
          this.setteim = new Date().getTime()
          if (this.scanValue) {
            // console.log('scanValue', this.scanValue)
            if (this.scanValue.includes('!')) {
              this.getItemDetails(this.scanValue.slice(1))
              this.timerKey = new Date().getTime()
            }
          }
          this.scanValue = ''
        }
      }, 1)
      window.addEventListener('keypress', e => {
        if (e.keyCode !== 13 && e.keyCode !== 16) {
          _this.scanValue += e.key
          // console.log('onScan---', _this.scanValue, e.keyCode)
          _this.setteim = new Date().getTime()
        }
      })
    },
    // 选择商品
    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
        })
        // 判断缓存数据中是否有选中过配送
        // eslint-disable-next-line array-callback-return
        const flag = store.some(el => {
          if (el.id === cartObj.id) {
            return el.isDistribution
          }
        })
        // console.log('flag', flag)
        if (currentInfo) {
          // console.log('currentInfo', currentInfo)
          // 存在数量叠加1
          currentInfo.shoppingNum = currentInfo.shoppingNum + 1
          if (currentInfo.shoppingNum > 999) {
            currentInfo.shoppingNum = 999
          }
          this.finallyCartList = [...store]
          // 购物车列表选中项
          this.shoppingCartActive = currentInfo
        } else {
          if (flag) {
            cartObj.isDistribution = flag
          }
          // 不存在追加在购物车列表前面
          this.finallyCartList = [cartObj, ...store]
          this.shoppingCartActive = cartObj
        }
      } else {
        /**
         * 不存在本地购物车数据逻辑
         */
        this.shoppingCartList = []
        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]
        // 购物车列表选中项
        this.shoppingCartActive = this.finallyCartList[0]
      }
      // 把最终购物车列表数据缓存在本地
      localStorage.setItem('finallyCartList', JSON.stringify(this.finallyCartList))
      // 初始化获取缓存数据
      this.cacheHandler()
    },
  }
}

一、需求

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 = []
        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 = []
        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)


你可能感兴趣的:(vue专栏,Vue,H5移动端项目,Vue3专栏,vue.js,移动端,ipad端,购物车,本地缓存,购物车功能,扫码枪)