vue实现淘宝购物车功能

所属分类: 网络编程 / JavaScript 阅读数: 214
收藏 0 赞 0 分享

本文实例为大家分享了vue实现淘宝购物车的具体代码,供大家参考,具体内容如下

淘宝购物车功能,效果如下图

非常简单的逻辑,没有做代码的封装,代码如下

<div class="list-container">
    <div class="top-ops">
        <div>
          <img src="../../../static/images/HomeRecommendShopInfoAdress@2x.png" alt="">
          <span>浙江省杭州市...</span>
        </div>
        <div class="ops">
          <span v-if="cartStatus === 'account'" @click="cartStatus = 'edit'">编辑商品</span>
          <span v-if="cartStatus === 'edit'" @click="cartStatus = 'account'">完成</span>
        </div>
    </div>
    <div class="paddingB200">
      <div class="shop-list" v-for="(item,index) in cartShops" :key="index">
        <div class="shop-name">
          <label>
            <input type="checkbox"
              name="shopRadio"
              :value="item.productShopId"
              @click="shopCheck($event,cartShops)"
            class="disN">
            <b></b>
          </label>
          <div>
            <div>
              <img src="../../../static/images/mall@2x.png" alt="">
              <span class="name">{{item.shopName}}</span>
            </div>
            <span>
              <img src="../../../static/images/jtxq@2x.png" alt="">
            </span>
          </div>
        </div>
        <div class="goods-list" v-for="(goods,goodsIndex) in item.detailLists" :key="goodsIndex">
          <label>
            <input type="checkbox"
              name="goodRadio"
              :price="goods.price"
              :num="goods.number" :dataId="item.productShopId"
              :value="goods.cartDetailId"
              @click="goodsCkeck($event,item.detailLists,cartShops,item.productShopId)"
            class="disN">
            <b></b>
          </label>
          <div class="middle">
            <img :src="goods.reportImage" alt="">
            <div>
              <p class="name">{{goods.name}}</p>
              <p class="spec">{{goods.specifications}}</p>
              <p class="tab">
                <img src="../../../static/images/lsspbq@2x.png" alt="">
              </p>
            </div>
          </div>
          <div class="right">
            <p class="price">¥{{goods.price}}</p>
            <p class="num">X{{goods.number}}</p>
            <p class="caculate">
              <span class="mark" @click="numDecrease(goods.number)"></span>
              <span class="beeforCacul">{{goods.number}}</span>
              <span class="cacul" :num="goods.cartDetailId">{{goods.number}}</span>
              <span class="mark" @click="numAdd(goods.number)"></span>
            </p>
          </div>
        </div>
      </div>
      <div class="edit" v-if="cartStatus === 'edit'">
        <label>
          <input type="checkbox" name="allRadio" class="disN" @click="allCheck($event)">
          <b></b>
          <span>全选</span>
        </label>
        <span class="delet">删除(3)</span>
      </div>
      <div class="gotopay" v-if="cartStatus === 'account'">
        <label>
          <input type="checkbox" name="allRadio" class="disN" @click="allCheck($event)">
          <b></b>
          <span class="marginR40">全选</span>
          <span>合计:</span>
          <span class="sum">¥{{sumPrice.toFixed(2)}}</span>
        </label>
        <span class="delet" @click="cauSum">去结算({{totalNumber}})</span>
      </div>
    </div>
</div>
export default {
  components: {
     
  },
  name: "life",
  data() {
    return {
      cartStatus:"account", //购物车状态,account结算,edit删除编辑状态
      cartShops: [], //店铺列表
      sumPrice:0, //合计金额
      totalNumber: 0, //总数
      shopList:[], //店铺列表
      goodsList:[], //商品列表
    };
  },
  watch: {
     
  },
  mounted() {
    this.getCartDetail();           
  },
  methods: {
    //购物车列表
    getCartDetail: function(){
      this.$http.get("api/product/v1/getCartDetail").then( res => {
        if(res.data.code === 200){
          //console.log(res.data.data)
          this.cartShops = res.data.data.cartShops;
        }else{
          Toast(res.data.msg);
        }
      }).catch( error => {
        console.log(error)
      })
    },
    //商品选择
    goodsCkeck: function(event,goodsList,shopList,shopId){                 
      //商品列表+-,店铺是否checked(店铺列表+-),全选是否checked
      var input = document.getElementsByTagName('input')
      if(event.currentTarget.checked){
        this.goodsList.push(String(event.currentTarget.value));
        //如果店铺内所有商品全选,店铺选中
        var newArr = this.goodsList;
        var tt = goodsList.every(function(itemValue){
          return (newArr.indexOf(String(itemValue.cartDetailId)) != -1)
        })
        if(tt){
          //店铺内全选,店铺checked,店铺列表+
          for(var i = 0;i<input.length;i++){
            if(input[i].value == shopId){
              input[i].checked = true;
            }
          }
          this.shopList.push(String(shopId)); //防止shopid是number类型造成麻烦
          //如果所有店铺都全选,则全选按钮checked
          if(this.shopList.length === shopList.length){
            //所有店铺全选
            for(var i = 0;i<input.length;i++){
              if(input[i].name == 'allRadio'){
                input[i].checked = true;
              }
            }
          }
        }
      }else{
        //商品列表--
        this.goodsList.splice(this.goodsList.indexOf(event.currentTarget.value),1)
        //如果店铺checked,则取消,店铺列表--
        for(var i = 0;i<input.length;i++){
          if(input[i].value == shopId){
            if(input[i].checked){
              input[i].checked = false;
              this.shopList.splice(this.shopList.indexOf(String(shopId)),1); //防止shopid是number类型造成麻烦
            }
          }
          //任意一个不选,全选取消
          if(input[i].name == 'allRadio'){
            input[i].checked = false;
          }
        }
      }
      //计算总价和数量
      this.caculate();
    },
    //店铺选择
    shopCheck: function(event,shopList){
      //店铺选中则对应商品全选,否则全不选
      //console.log(event.currentTarget)
      var input = document.getElementsByTagName('input')
      if(event.currentTarget.checked){
        //店铺列表+,店铺checked,店铺内商品全checked,商品列表++
        //console.log(this.shopList)
        this.shopList.push(String(event.currentTarget.value));
        //店铺内商品全checked
        for(var i = 0;i<input.length;i++){
          if(input[i].getAttribute('dataId') == event.currentTarget.value){
            //将没有选中的checked,并加入列表,去重
            if(!input[i].checked){
              input[i].checked = true;
              //商品列表++
              this.goodsList.push(String(input[i].value))
            }
          }
        }
        //所有店铺全选
        if(this.shopList.length === shopList.length){
          for(var i = 0;i<input.length;i++){
            if(input[i].name == 'allRadio'){
              input[i].checked = true;
            }
          }
        }
      }else{
        //店铺取消checked,店铺列表--,店铺内所有商品取消checked,商品列表--
        this.shopList.splice(this.shopList.indexOf(String(event.currentTarget.value)),1);
        //店铺内所有商品取消checked
        for(var i = 0;i<input.length;i++){
          if(input[i].getAttribute('dataId') == event.currentTarget.value){
            input[i].checked = false;
            //商品列表--
            this.goodsList.splice(this.goodsList.indexOf(input[i].value),1);
          }
          //任意一个不选,全选取消
          if(input[i].name == 'allRadio'){
            input[i].checked = false;
          }
        }
      }
      //计算总价和数量
      this.caculate();
    },
    //所有全选
    allCheck: function(event){
      var input = document.getElementsByTagName('input')
      if(event.currentTarget.checked){
        //全选checked,所有店铺checked,店铺列表++,所有商品checked,商品列表++
        for(var i = 0;i<input.length;i++){
          //去重
          if(!input[i].checked){
            input[i].checked = true;
            if(input[i].name == 'shopRadio'){
              this.shopList.push(String(input[i].value))
            }
            if(input[i].name == 'goodRadio'){
              this.goodsList.push(String(input[i].value))
            }
          }
        }
      }else{
        //全不选取消checked,店铺全部取消checked,店铺列表清空,所有商品取消checked,商品列表清空
        for(var i = 0;i<input.length;i++){
          input[i].checked = false;
          this.shopList = [];
          this.goodsList = [];
        }
      }
      //计算总价和数量
      this.caculate();
    },
    //计算总金额总数量
    caculate: function(){
      var input = document.getElementsByTagName('input');
      var newArr = [];
      for(var i = 0;i<input.length;i++){
        if(input[i].name == 'goodRadio' && input[i].checked){
          var num = input[i].parentNode.parentNode.children[2].children[2].children[2].innerHTML;
          newArr.push(
            {
              'price': input[i].getAttribute('price'),
              'num': num
            }
          )
        }
      }
      this.totalNumber = newArr.length;
      //归零
      this.sumPrice = 0;
      for(var j = 0,len = newArr.length;j<len;j++){
        this.sumPrice += newArr[j].price * newArr[j].num;
      }
    },
    //数量减小
    numDecrease: function(num){
      //如果当前input选中,则修改数量计算价格,如果当前input没有选中,则修改数量不计算价格
      var spanList = event.currentTarget.parentNode.children;
      for(var i = 0,len = spanList.length;i<len;i++){
        if(spanList[i].getAttribute("class") == 'beeforCacul'){
          spanList[i].style.display = 'none';
        }
        if(spanList[i].getAttribute("class") == 'cacul'){
          spanList[i].style.display = 'block';
          var caculNum = spanList[i].innerHTML;
          if(caculNum < 2){
            Toast('宝贝不能再少了哦');
          }else{
            caculNum --
            spanList[i].innerHTML = caculNum;
          }
        }
      }
      if(event.currentTarget.parentNode.parentNode.parentNode.children[0].children[0].checked){
        this.caculate();
      }
    },
    //数量增加
    numAdd: function(num){
      var spanList = event.currentTarget.parentNode.children;
      //console.log(event.currentTarget.parentNode.children)
      for(var i = 0,len = spanList.length;i<len;i++){
        if(spanList[i].getAttribute("class") == 'beeforCacul'){
          spanList[i].style.display = 'none';
        }
        if(spanList[i].getAttribute("class") == 'cacul'){
          spanList[i].style.display = 'block';
          var caculNum = spanList[i].innerHTML;
          caculNum ++;
          spanList[i].innerHTML = caculNum;
        }
      }
      if(event.currentTarget.parentNode.parentNode.parentNode.children[0].children[0].checked){
        this.caculate();
      }
    },
    //去结算
    cauSum:function(){
      if(this.sumPrice === 0){
        Toast('您还没有选择宝贝哦');
      }else{
        this.$router.push('/cart/order')
      }
    },
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

jQuery中图片展示插件highslide.js的简单dom

前言 今天用用了一款图片展示插件highslide.js,感觉用起来很是舒畅,几乎不用怎么写代码,只需要知道如何写参数就行了。 那么这么牛叉的插件我们该如何用哪,下面我就跟大家讲解一下。 一、引入 首先我们运用绝对路径引入,这一般都是在实际项目中引用的方法,我们下载时候会... 查看详情
收藏 0 赞 0 分享

基于vue-ssr的静态网站生成器VuePress 初体验

什么是VuePress VuePress由两部分组成:一个基于Vue的轻量级静态网站生成器,以及为编写技术文档而优化的默认主题。 它是为了满足Vue自己的子项目文档的需求而创建的。 VuePress为每一个由它生成的页面提供预加载的html,不仅加载速度极佳,同时对s... 查看详情
收藏 0 赞 0 分享

Angular数据绑定机制原理

1.Angular.js扩展浏览器的事件循环 浏览器持续等待例如用户交互这样的事件。当你在一个<input>标签里输入字符之后,这个事件的回调函数在JS解释器中执行了其包含的DOM操作,执行完毕后,浏览器响应地对DOM做出了变化。Angular拓展了这个事件循环,使... 查看详情
收藏 0 赞 0 分享

微信小程序如何像vue一样在动态绑定类名

小程序 开发中遇到这样一个问题... 排行榜开发的时候,前三名的样式不同,其余的样式一样。但是都是通过同一元素来遍历的,当时卡了一下。后来发现有module模块化这一概念,于是查了下api,一下子就做出来了。   就是不同名次上边的样式根据实际情况展示效果。 模... 查看详情
收藏 0 赞 0 分享

Vue进度条progressbar组件功能

效果图 首先我们看一下进度条组件运行出来的效果,如下图显示 进度条组件 实现过程 ◾ 项目搭建 progressbar组件在一个可以直接运行的npm包,通过Yeoman进行构建,再通过Gulp+Webpack构建工具,生成的工作目录如下,其中各个文件夹的... 查看详情
收藏 0 赞 0 分享

redux中间件之redux-thunk的具体使用

redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree 。创建store的时候需要传入reducer,真正能改变store中数据的是store.dispat... 查看详情
收藏 0 赞 0 分享

JS实现二维数组横纵列转置的方法

我想将一个二维数组横纵列转过来,我就不信只有我有这个需求,可是百度了好久,四海八荒都找遍了…… 后来证明还是大神说的google好用 ~ 第一条就是,鄙视臭百度 此番记录下来,也方便各位道友查阅(好想说“仙友”,最近被一部剧毒害的后遗症 ~~~) var n... 查看详情
收藏 0 赞 0 分享

关于Angularjs中跨域设置白名单问题

在config中注入$sceDelegateProvider服务使用resourceUrlWhitelist([])方法添加白名单      跨域时将method的属性设置为"jsonp"就可以访问了 app.config(["... 查看详情
收藏 0 赞 0 分享

浅析vue中常见循环遍历指令的使用 v-for

vue中循环遍历使用的指令是v-for 1.v-for遍历数组 (1)value in arr 遍历数组中的元素 (2)(value,index) in arr 遍历数组中的元素和数组下标 运行代码: <body> <div class=... 查看详情
收藏 0 赞 0 分享

vue双向数据绑定知识点总结

1.原理 vue的双向数据绑定的原理相信大家都十分了解;主要是通过ES5的Object对象的defineProperty属性;重写data的set和get函数来实现的 所以接下来不使用ES6进行实际的代码开发;过程中如果函数使用父级this的情况;还是使用显示缓存中间变量... 查看详情
收藏 0 赞 0 分享
查看更多