【vue3.0】18.0 某东到家(十八)——优化代码、数据永久性存储localStorage

目的:打造购物车的页面

"去结算"调整

调整src\views\shop\Cart.vue


......


优化if语句

src\store\index.js

import { createStore } from 'vuex'

export default createStore({
  state: {
    cartList: {
      // 第一层级:商铺的id
      // 第二层内容是商品内容以及购物数量
      // shopId: {
      //   productID: {
      //     _id: '1',
      //     name: '番茄250g/份',
      //     imgUrl: '/i18n/9_16/img/tomato.png',
      //     sales: 10,
      //     price: 33.6,
      //     oldPrice: 39.6,
      //     count: 0
      //   }
      // }
    }
  },
  mutations: {
    /**
     * 加入或减少购物车数量
     * @param {*} state
     * @param {String} shopId 店铺id
     * @param {String} productId 商品id
     * @param {Object} productInfo 商品信息集
     * @param {Number} num 加入购物车的数量
     * @param {*} payload
     */
    changeItemToCart(state, payload) {
      const { shopId, productId, productInfo, num } = payload
      // console.log(shopId, productId, productInfo)
      const shopInfo = state.cartList[shopId] || {}

      let product = shopInfo[productId]
      if (!product) {
        productInfo.count = 0
        product = productInfo // 初始化
      }

      product.count += num
      // && 短路运算符,前面的满足才会执行后面的逻辑,等价于if
      num > 0 && (product.checked = true)

      product.count <= 0 && (shopInfo[productId].count = 0)
      // delete state.cartList[shopId]

      shopInfo[productId] = product
      // 赋值
      state.cartList[shopId] = shopInfo
    },
    // 购物车勾选记录
    changeItemChecked(state, payload) {
      const { shopId, productId } = payload
      const product = state.cartList[shopId][productId]
      product.checked = !product.checked
    },
    // 清除购物车
    changeCleanCartProducts(state, payload) {
      const { shopId } = payload
      state.cartList[shopId] = {}
    },
    // 购物车全选或者取消全选
    setCartItemsChecked(state, payload) {
      const { shopId } = payload
      const products = state.cartList[shopId]
      if (products) {
        for (const i in products) {
          const product = products[i]
          product.checked = true
        }
      }
    }
  },
  actions: {},
  modules: {}
})

之前存入src\store\index.js

      // 第一层级:商铺的id
      // 第二层内容是商品内容以及购物数量
      // shopId: {
      //   productID: {
      //     _id: '1',
      //     name: '番茄250g/份',
      //     imgUrl: '/i18n/9_16/img/tomato.png',
      //     sales: 10,
      //     price: 33.6,
      //     oldPrice: 39.6,
      //     count: 0
      //   }
      // }

在订单层面,需要显示商品名字等商铺的信息,明显这个结构不够用。优化结构如下:

      // shopId: {
      //   shopName: '沃什么码',
      //   productList: {
      //     productId: {
      //       _id: '1',
      //       name: '番茄250g/份',
      //       imgUrl: '/i18n/9_16/img/tomato.png',
      //       sales: 10,
      //       price: 33.6,
      //       oldPrice: 39.6,
      //       count: 0
      //     }
      //   }
      // }

那么相应的更新代码也要调整:
src\store\index.js

import { createStore } from 'vuex'

export default createStore({
  state: {
    cartList: {
      // shopId: {
      //   shopName: '沃什么码',
      //   productList: {
      //     productId: {
      //       _id: '1',
      //       name: '番茄250g/份',
      //       imgUrl: '/i18n/9_16/img/tomato.png',
      //       sales: 10,
      //       price: 33.6,
      //       oldPrice: 39.6,
      //       count: 0
      //     }
      //   }
      // }
      // ================== 之前版本的结构 ==================
      // 第一层级:商铺的id
      // 第二层内容是商品内容以及购物数量
      // shopId: {
      //   productID: {
      //     _id: '1',
      //     name: '番茄250g/份',
      //     imgUrl: '/i18n/9_16/img/tomato.png',
      //     sales: 10,
      //     price: 33.6,
      //     oldPrice: 39.6,
      //     count: 0
      //   }
      // }
    }
  },
  mutations: {
    /**
     * 加入或减少购物车数量
     * @param {*} state
     * @param {String} shopId 店铺id
     * @param {String} productId 商品id
     * @param {Object} productInfo 商品信息集
     * @param {Number} num 加入购物车的数量
     * @param {*} payload
     */
    changeItemToCart(state, payload) {
      const { shopId, productId, productInfo, num } = payload
      // console.log(shopId, productId, productInfo)
      const shopInfo = state.cartList[shopId] || {
        shopName: '',
        productList: {}
      }

      let product = shopInfo?.productList[productId]
      if (!product) {
        productInfo.count = 0
        product = productInfo // 初始化
      }

      product.count += num
      // && 短路运算符,前面的满足才会执行后面的逻辑,等价于if
      num > 0 && (product.checked = true)

      product.count <= 0 && (shopInfo[productId].count = 0)
      // delete state.cartList[shopId]

      shopInfo.productList[productId] = product
      // 赋值
      state.cartList[shopId] = shopInfo
    },
    // 购物车勾选记录
    changeItemChecked(state, payload) {
      const { shopId, productId } = payload
      const product = state.cartList[shopId].productList[productId]
      product.checked = !product.checked
    },
    // 清除购物车
    changeCleanCartProducts(state, payload) {
      const { shopId } = payload
      state.cartList[shopId].productList = {}
    },
    // 购物车全选或者取消全选
    setCartItemsChecked(state, payload) {
      const { shopId } = payload
      const products = state.cartList[shopId].productList
      if (products) {
        for (const i in products) {
          const product = products[i]
          product.checked = true
        }
      }
    },
    /**
     * 修改商店名称
     * @param {Object} state vuex对象
     * @param {Object} payload 传值
     */
    changeShopName(state, payload) {
      const { shopId, shopName } = payload
      const shopInfo = state.cartList[shopId] || {
        shopName: '',
        productList: {}
      }
      shopInfo.shopName = shopName
      state.cartList[shopId] = shopInfo
    }
  },
  actions: {},
  modules: {}
})

src\views\shop\Shop.vue






src\views\shop\Content.vue







src\views\shop\commnCartEffect.js

import { toRefs } from 'vue'
import { useStore } from 'vuex'
// 添加、减少到购物车功能
export const useCommonCartEffect = () => {
  const store = useStore()
  const { cartList } = toRefs(store.state)
  /**
   * 加入或减少购物车数量
   * @param {String} shopId 店铺id
   * @param {String} productId 商品id
   * @param {Object} productInfo 商品信息集
   * @param {Number} num 加入购物车的数量
   */
  const changeCartItemInfo = (shopId, productId, productInfo, num) => {
    console.log(
      'changeCartItemInfo:',
      'shopId:' + shopId,
      'productId:' + productId,
      'productInfo:' + JSON.stringify(productInfo),
      'num:' + num
    )
    // 更新vuex中的值
    store.commit('changeItemToCart', { shopId, productId, productInfo, num })
  }

  return { cartList, changeCartItemInfo }
}

src\views\shop\Cart.vue





最终效果如下:


image.png

继续优化一下src\views\shop\Content.vue中的流程代码:


优化购物车为空时,全选和清空购物车也不显示,修改src\views\shop\Cart.vue: