Vue实现购物车完整代码

项目拖得比较长,做删除功能的时候完善一下,总价和总数使用计算属性即可

其实之前也做过几次购物车,但是没有保留代码,这次pc端有需求类似京东购物车,效果图如下

有疑问欢迎咨询哦

 <ul class="order_lists cartTop">
                        <li class="list_chk">
              <!--所有商品全选-->
              <input type="checkbox" v-model="fetchData.isSelectAll" id="all" class="whole_check" @click="cartchoose()">
              <label for="all" :class="fetchData.status?'mark':''"></label>
            </li>
            <li class="list_con">产品类别/检测对象</li>
            <li class="list_info">项目/参数</li>
            <li class="list_way">方法标准</li>
            <li class="list_limit">限制范围</li>
            <li class="list_price">单价</li>
            <li class="list_count">数量</li>
            <li class="list_op">操作</li>
          </ul>
<div class="cartBox" v-for="(item,i) in fetchData.list" :key="i">
          <div class="shop_info">
            <div class="all_check">
              <input type="checkbox" v-model="item.check" id="shop_a" class="shopChoice" @change="shopchoose(item)">
            </div>
            <div class="shop_name">
              <strong>{{item.shop_name}}</strong>
            </div>
          </div>
          <div class="order_content">
            <ul class="order_lists order_things" v-for="(pro,i) in item.products" :key="i">
              <li class="list_chk">
                <input type="checkbox" v-model="pro.checked" id="checkbox_2" class="son_check" @change="choose(item,pro)">
              </li>
              <li class="list_con">
                {{pro.text}}
              
              </li>
              <li class="list_info">
                <p>侧泵仪</p>
              </li>
              <li class="list_way">
                高功率微波能量
              </li>
              <li class="list_limit">
                气敏色谱
              </li>

              <li class="list_price">
                <p class="sum_price">{{pro.sum}} X 1</p>
              </li>
              <li class="list_count">
                <div class="amount_box">
                  <span class="reduce reSty" @click="reduce(pro)">-</span>
                  <input type="text" v-model="pro.num" class="count">
                  <span class="plus" @click="add(pro)">+</span>
                </div>
              </li>
              <li class="list_op">
                <p class="collect"><a href="javascript:;" class="colBtn">添加到收藏</a></p>
                <p class="del" @click="handleDelete()">删除</p>
              </li>
            </ul>
          </div>
        </div>
 <!--底部-->
        <el-row type="flex" justify="end" :gutter="20">
          <el-col :span="6">
            <div class="goods">已选商品 <strong class="goods_count"> {{totalCount}} </strong> 件,共计: <strong class="total_text">¥{{totalPrice}}</strong></div>

          </el-col>
          <el-col :span="3">
            <el-button class="defaultBtn payBtn">去 结 算</el-button>
          </el-col>
        </el-row>
<style lang="scss" scoped>
.cartMain {
  margin-top: 40px;
}
.order_lists {
  display: flex;
  li {
    padding: 10px 10px;
    line-height: 25px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
  }
}
.cartTop li {
  font-size: 16px;
  // font-weight: bold;
}
.list_chk {
  width: 5%;
}
.list_count,
.list_limit,
.list_price,
.list_op {
  width: 11%;
}
.list_info,
.list_con {
  width: 15%;
}
.list_way {
  width: 20%;
}
.cartTop {
  background: #e4e7ed;
}
.cartBox {
  margin: 10px 0;
  .shop_info {
    border-bottom: 2px solid #dcdcdc;
    padding: 10px 25px;
    .all_check {
      float: left;
      margin-right: 15px;
    }
  }
  .count {
    width: 50px;
  }
  .amount_box {
    display: flex;
    align-items: center;
    span {
      display: inline-block;
      border: 1px solid #cacaca;
      height: 20px;
      line-height: 20px;
      padding: 0 6px;
      cursor: pointer;
    }
    input {
      height: 20px;
      border: 1px solid #cacaca;
      text-align: center;
    }
  }

  .order_things {
    border-bottom: 1px solid #eeeeee;
    border-left: 1px solid #eeeeee;
    border-right: 1px solid #eeeeee;
    .list_op {
      display: block;
      text-align: center;
      p {
        cursor: pointer;
      }
    }
  }
}

.payBtn {
  width: 100%;
}
.goods {
  color: #202020;
  height: 100%;
  display: flex;
  align-items: center;
  font-size: 14px;
  strong {
    font-size: 18px;
    font-weight: bold;
    color: #e52626;
    margin: 0 5px;
  }
}
</style>

data中模拟数据

 fetchData: {
        list: [
          {
            shop_id: 1,
            shop_name: '搜猎人艺术生活',
            products: [
              {
                pro_id: 101,
                text: '商品名1',
                price: 480,
                num: 1,
                img: './images/1.png',
                sum: 480,
                checked: false //商品选中状态
              },
              {
                pro_id: 102,
                text: '筆記本筆記本筆記本筆記本筆記本筆記本筆記本筆記本筆記本筆記本',
                price: 680,
                num: 1,
                img: './images/2.png',
                sum: 680,
                checked: false
              },
              {
                pro_id: 103,
                text: '產品2',
                price: 380,
                num: 1,
                img: './images/3.png',
                sum: 380,
                checked: false
              }
            ],
            check: false, //店铺选中状态
            chooseNum: 0 //商品选中个数
          },
          {
            shop_id: 2,
            shop_name: '卷卷旗舰店',
            products: [
              {
                pro_id: 201,
                text: '鍵盤鍵盤鍵盤鍵盤鍵盤鍵盤鍵盤鍵盤',
                price: 580,
                num: 1,
                img: './images/4.png',
                sum: 580,
                checked: false
              },
              {
                pro_id: 202,
                text: '鼠標鼠標鼠標鼠標鼠標',
                price: 780,
                num: 1,
                img: './images/5.png',
                sum: 780,
                checked: false
              }
            ],
            check: false,
            chooseNum: 0
          },
          {
            shop_id: 3,
            shop_name: '瓜皮的神秘商店',
            products: [
              {
                pro_id: 301,
                text: '眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片眼镜片',
                price: 180,
                num: 1,
                img: './images/6.png',
                sum: 180,
                checked: false
              },
              {
                pro_id: 302,
                text: '凑数的凑数的凑数的凑数的凑数的凑数的凑数的凑数的',
                price: 280,
                num: 1,
                img: './images/7.png',
                sum: 280,
                checked: false
              }
            ],
            check: false,
            chooseNum: 0
          }
        ],
        isSelectAll: false, //全选选中状态
        allchoose: 0, //店铺选中个数
      }

methods中的方法

    choosetrue(item, pro) {
      pro.checked = true //商品选中
      item.chooseNum++ //选中商品数量先+1
      item.chooseNum === item.products.length ? (item.check = true) : '' //再与该店铺商品数量比较,若相等則店铺选中

      item.check
        ? this.fetchData.allchoose++ === this.fetchData.list.length
          ? (this.fetchData.isSelectAll = true)
          : (this.fetchData.isSelectAll = false)
        : '' //如果店铺选中状态改为true,选中店铺数量先+1,再与店铺数量比较,如果相等就更改全选选中状态为true
    },
    choosefalse(item, pro) {
      pro.checked = false //将商品选中状态改为false
      item.chooseNum--
      if (item.check) {
        item.check = false //如果店铺是被选中的,更改店铺选中状态
        this.fetchData.allchoose-- //并且选中店铺数量-1
      }
      this.fetchData.isSelectAll = false //全选的状态,直接改为false

    },
    choose(item, pro) {
      pro.checked ? this.choosetrue(item, pro) : this.choosefalse(item, pro)
    },
    // 店鋪
    shopchoose(item) {
      item.check ? this.shoptrue(item) : this.shopfalse(item)
    },
    shoptrue(item) {
      item.products.forEach(pro => {
        pro.checked === false ? this.choosetrue(item, pro) : ''
      })
    },
    shopfalse(item) {
      item.products.forEach(pro => {
        pro.checked === true ? this.choosefalse(item, pro) : ''
      })
    },
    cartchoose() {
      this.fetchData.isSelectAll = !this.fetchData.isSelectAll //取反改变状态
      this.fetchData.isSelectAll
        ? this.fetchData.list.forEach(item => this.shoptrue(item))
        : this.fetchData.list.forEach(item => this.shopfalse(item))
    }, //根据取反后的状态进行相应的店铺按钮操作
    add(obj) {
      obj.num++
      obj.sum += obj.price
     
    },
    reduce(obj) {
      if (obj.num === 1) {
        obj.num
      } else {
        obj.num--
        obj.sum -= obj.price
      
      }
    },

我的项目需求是上次选中的数据接口中会有记录,所以修改为计算属性实现总价,这样做删除功能的时候总价也会自动变化,很方便(已经对过接口,所以下面的字段和data中的不对应,大家自行修改下)

computed: {
     totalPrice: function () {
        let totalPrice = 0;
        this.fetchData.list.forEach((item) => {
          item.products.forEach(val => {
            if(val.pitchOnFlag){
              totalPrice += val.count*val.price
            }
          })
        })

        return totalPrice;
     },
     totalCount:function(){
      let totalCount = 0;
        this.fetchData.list.forEach((item) => {
          item.products.forEach(val => {
            if(val.pitchOnFlag){
              totalCount += val.count
            }
          })
        })

        return totalCount;
     },
   
  },

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值