上一篇文章完成了基础的商品列表:Vue3.0 简单商城—商品列表组件 – 每天进步一点点

这篇文章介绍一下购物车组件。

基本逻辑:当我们点击“加入购物车时”,会把相应的产品加入到购物车中。

一、修改商品列表组件

我们修改商品列表组件,完善“加入购物车”功能,使用户点击“加入购物车”时,可以将相应的数据存入到本地缓存中。

先修改商品信息,增加num 字段,用来表示商品的数量。

          id:'1003',
          name: '西瓜',
          price: 30,
          description: '新鲜的大西瓜',
          image: 'https://img2.baidu.com/it/u=3734188370,3061921446&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200',
          num:0,

那么,整个商品列表组件修改为如下:

<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="6" v-for="(product, index) in products" :key="index">
        <el-card :body-style="{ padding: '0px' }" class="product-card">
          <img :src="product.image" class="image" />
          <div style="padding: 14px">
            <span>{{ product.name }}</span>
            <div class="bottom">
              <span class="price">¥{{ product.price }}</span>
              <el-button type="text" class="button">查看详情</el-button>
              <el-button type="text" class="button" @click="addToCar(product)"
                >加入购物车</el-button
              >
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
// import homeApi from "../../api/homeApi";

export default {
  data() {
    return {
      products: [
        {
          id: "1001",
          name: "草莓",
          price: 37,
          description: "新鲜的大草莓",
          image:
            "https://img0.baidu.com/it/u=1884825130,1214737831&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
          num: 0,
        },
        {
          id: "1002",
          name: "苹果",
          price: 15,
          description: "新鲜的苹果",
          image:
            "https://img0.baidu.com/it/u=3289470460,166095271&fm=253&fmt=auto&app=120&f=JPEG?w=183&h=183",
          num: 0,
        },
        {
          id: "1003",
          name: "西瓜",
          price: 30,
          description: "新鲜的大西瓜",
          image:
            "https://img2.baidu.com/it/u=3734188370,3061921446&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
          num: 0,
        },
        {
          id: "1004",
          name: "香蕉",
          price: 8.5,
          description: "新鲜的香蕉",
          image:
            "https://img0.baidu.com/it/u=3106970920,4028332390&fm=253&fmt=auto&app=120&f=JPEG?w=193&h=193",
          num: 0,
        },
        {
          id: "1005",
          name: "哈密瓜",
          price: 17,
          description: "新鲜的哈密瓜",
          image:
            "https://img1.baidu.com/it/u=3415357883,3105635612&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200",
          num: 0,
        },
      ],
    };
  },

  methods: {
    //添加到购物车(使用localStorage存储)
    addToCar(e) {
      this.$message.success('添加'+e.name+"到购物车成功");
      //console.log(e);
      //根据id,每有一个,就增加一个num属性,
      let flag = false;
      //先检查有没有这个数据
      if (localStorage.getItem("carList")) {
        let carList = [];
        carList = JSON.parse(localStorage.getItem("carList"));
        console.log(carList);
        //看看数组里面有没有当前这个数组
        for (let index = 0; index < carList.length; index++) {
          const element = carList[index];
          //console.log(element);
          if (e.id == element.id) {
            carList[index].num++;
            flag = true; //能匹配上
          }
          console.log(carList[index]);
        }
        if (flag == false) {
          //没有匹配就新增
          carList.push(e);
        }
        localStorage.setItem("carList", JSON.stringify(carList));
      } else {
        let carList = [];
        carList.push(e);
        localStorage.setItem("carList", JSON.stringify(carList)); // 将数据存入到本地存储中。
      }
    },
  },

  mounted() {
    //homeApi.methods.getWeather(101120201);
  },
};
</script>

<style  >
.product-card {
  margin-bottom: 20px;
}

.image {
  width: 100%;
  display: block;
}

.bottom {
  margin-top: 13px;
  line-height: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.price {
  font-size: 18px;
  color: #f56c6c;
}

.button {
  padding: 0;
  min-height: auto;
}
</style>

效果如下:

二、购物车组件

购物车组件的基本逻辑是:当组件加载时,先从本地缓存中获取购物车数据,然后将数据渲染到页面上,最后统一计算数据。

我们使用table组件来表示购物车功能。

基础参考代码如下:

<template>
  <div>
    <el-card>
      <el-table :data="cart" style="width: 100%">
        <el-table-column
          prop="name"
          label="商品名称"
          width="180"
        ></el-table-column>
        <el-table-column
          prop="price"
          label="价格"
          width="180"
        ></el-table-column>
        <el-table-column label="数量"  prop="num">
          <template v-slot="scope">
            <el-input-number
              v-model="scope.row.num"
              :min="1"
              :max="99"
              @change="updateTotalPrice"
            ></el-input-number>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="scope">
            <el-button @click="removeFromCart(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-row :gutter="20">
        <el-col :span="12">总价: {{ totalPrice }}</el-col>
        <el-col :span="12">
          <el-button type="primary">合并付款</el-button></el-col>
      </el-row>
    </el-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cart: [],  //购物车数据
      totalPrice:0
    };
  },
  components: {},
  methods: {},
  
  mounted() {
       if (localStorage.getItem("carList")) {
           this.cart = JSON.parse(localStorage.getItem("carList"));
           //初次加载需要计算价格
           var sum=0
           for (let index = 0; index <  this.cart .length; index++) {
            const element =  this.cart [index];
            sum+=element.price * element.num;
           } 
           this.totalPrice=sum;
       }
       
  },
};
</script>

<style  >
</style>
三、完善数量变化与删除操作

我们增加计算总价格的函数:

//重新计算价格的方法:
    caclPrice(){
       var sum=0
           for (let index = 0; index <  this.cart .length; index++) {
            const element =  this.cart [index];
            sum+=element.price * element.num;
           } 
           this.totalPrice=sum;
    },

那么不论我们是删除数据,还是更新商品的数量,都会重新计算价格。

参考代码如下:

vue.car

<template>
  <div>
    <el-card>
      <el-table :data="cart" style="width: 100%">
        <el-table-column
          prop="name"
          label="商品名称"
          width="180"
        ></el-table-column>
        <el-table-column
          prop="price"
          label="价格"
          width="180"
        ></el-table-column>
        <el-table-column label="数量"  prop="num">
          <template v-slot="scope">
            <el-input-number
              v-model="scope.row.num"
              :min="1"
              :max="99"
              @change="updateTotalPrice()"
            ></el-input-number>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="scope">
            <el-button @click="removeFromCart(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-row :gutter="20">
        <el-col :span="12">总价: {{ totalPrice }}</el-col>
        <el-col :span="12">
          <el-button type="primary">合并付款</el-button></el-col>
      </el-row>
    </el-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cart: [],  //购物车数据
      totalPrice:0
    };
  },
  components: {},
  methods: {
    //移除一条数据
    removeFromCart(row){
       const index = this.cart.findIndex(item => item.id === row.id);
      if (index !== -1) {
        this.cart.splice(index, 1);
        //重新计算价格
        this.caclPrice()
        //更新缓存数据
          localStorage.setItem("carList", JSON.stringify(this.cart));
      }
    },
    //重新计算价格的方法:
    caclPrice(){
       var sum=0
           for (let index = 0; index <  this.cart .length; index++) {
            const element =  this.cart [index];
            sum+=element.price * element.num;
           } 
           this.totalPrice=sum;
    },
    updateTotalPrice(){
      console.log(11)
      //重新计算价格
      this.caclPrice()
      //更新缓存
      localStorage.setItem("carList", JSON.stringify(this.cart));
    }
  },
  
  mounted() {
       if (localStorage.getItem("carList")) {
           this.cart = JSON.parse(localStorage.getItem("carList"));
           //初次加载需要计算价格
           var sum=0
           for (let index = 0; index <  this.cart .length; index++) {
            const element =  this.cart [index];
            sum+=element.price * element.num;
           } 
           this.totalPrice=sum;
       }
       
  },
};
</script>

<style  >
</style>

效果如下:

分类: 前端