使用vue实现多规格选择实例(SKU)


Posted in Javascript onAugust 23, 2019

做过商城项目的小伙伴们,相信大家多多少少都会接触到规格选择这个模块,也就是所说的SKU。

公司最近在做一个下单系统,这里面就涉及到这个SKU,说实话之前我是没有写过这个的,刚开始也是有点迷茫把,不知道该如何下手,因为要考虑到后端那边返回的数据结构、库存、多规格等等问题,然后各种百度,各种搜集资料,才慢慢懂了其中的逻辑,下面我就简单写个demo吧。

首先逻辑得清晰

  1. 定义一个数组把选中的值存储起来。
  2. 定义一个对象存储要匹配的数据。
  3. 把选中的值与存储的数据进行遍历查找与之匹配的值的库存,若库存为0按钮为灰色不能选择。

上代码 秒懂 哈哈

1.html

<template>
  <div class="wrap wrap-sku">
    <div class="product-box">
      <div class="product-content">
        <div class="product-delcom" v-for="(ProductItem,n) in simulatedDATA.specifications">
          <p>{{ProductItem.name}}</p>
          <ul class="product-footerlist clearfix">
            <li v-for="(oItem,index) in ProductItem.item"
              v-on:click="specificationBtn(oItem.name,n,$event,index)"
              v-bind:class="[oItem.isShow?'':'noneActive',subIndex[n] == index?'productActive':'']">
              {{oItem.name}}
            </li>
          </ul>
        </div>
        <p v-if="price" class="price">¥{{price}}</p>
      </div>
      <div class="product-footer">
        <a href="javascript:" rel="external nofollow" >立即购买</a>
      </div>
    </div>
  </div>
</template>

2.js

<script>
  export default {
    data() {
      return {
        simulatedDATA: { //模拟后台返回的数据 多规格
          "difference": [
            { //所有的规格可能情况都在这个数组里
              "id": "19",
              "price": "200.00",
              "stock": "19",
              "difference": "100,白色"
            },
            {
              "id": "20",
              "price": "100.00",
              "stock": "29",
              "difference": "200,白色"
            },
            {
              "id": "21",
              "price": "300.00",
              "stock": "10",
              "difference": "100,黑色"
            },
            {
              "id": "22",
              "price": "900.00",
              "stock": "0",
              "difference": "200,黑色"
            },
            {
              "id": "23",
              "price": "600.00",
              "stock": "48",
              "difference": "100,绿色"
            },
            {
              "id": "24",
              "price": "500.00",
              "stock": "40",
              "difference": "200,绿色"
            },
            {
              "id": "25",
              "price": "90.00",
              "stock": "0",
              "difference": "100,蓝色"
            },
            {
              "id": "26",
              "price": "40.00",
              "stock": "20",
              "difference": "200,蓝色"
            }
          ],
          "specifications": [
            { //这里是要被渲染字段
              "name": "尺寸",
              "item": [
                {
                  "name": "100",
                },
                {
                  "name": "200",
                }
              ]
            },
            {
              "name": "颜色",
              "item": [
                {
                  "name": "白色",
                },
                {
                  "name": "蓝色",
                },
                {
                  "name": "黑色",
                },
                {
                  "name": "绿色",
                }
              ]
            }
          ]
        },
        selectArr: [], //存放被选中的值
        shopItemInfo: {}, //存放要和选中的值进行匹配的数据
        subIndex: [], //是否选中 因为不确定是多规格还是单规格,所以这里定义数组来判断
        price:'' //选中规格的价钱
      }
    },
    methods: {
      specificationBtn: function (item, n, event, index) {
        var self = this;
        if (self.selectArr[n] != item) {
          self.selectArr[n] = item;
          self.subIndex[n] = index;
        } else {
          self.selectArr[n] = "";
          self.subIndex[n] = -1; //去掉选中的颜色
        }
        self.checkItem();
      },
      checkItem: function () {
        var self = this;
        var option = self.simulatedDATA.specifications;
        var result = []; //定义数组储存被选中的值
        for(var i in option){
          result[i] = self.selectArr[i] ? self.selectArr[i] : '';
        }
        for (var i in option) {
          var last = result[i]; //把选中的值存放到字符串last去
          for (var k in option[i].item) {
            result[i] = option[i].item[k].name; //赋值,存在直接覆盖,不存在往里面添加name值
            option[i].item[k].isShow = self.isMay(result); //在数据里面添加字段isShow来判断是否可以选择
          }
          result[i] = last; //还原,目的是记录点下去那个值,避免下一次执行循环时被覆盖
        }
        if(this.shopItemInfo[result]){
          this.price = this.shopItemInfo[result].price || ''
        }
        self.$forceUpdate(); //重绘
      },
      isMay: function (result) {
        for (var i in result) {
          if (result[i] == '') {
            return true; //如果数组里有为空的值,那直接返回true
          }
        }
        return this.shopItemInfo[result].stock == 0 ? false : true; //匹配选中的数据的库存,若不为空返回true反之返回false
      }
    },
    created: function () {
      var self = this;
      for (var i in self.simulatedDATA.difference) {
        self.shopItemInfo[self.simulatedDATA.difference[i].difference] = self.simulatedDATA.difference[i]; //修改数据结构格式,改成键值对的方式,以方便和选中之后的值进行匹配
      }
      self.checkItem();
    }
  }
</script>

3.css

<style lang="scss" rel="stylesheet">
  .wrap-sku {
    .product-box {
      width: 1200px;
      display: block;
      margin: 0 auto;
    }
    .product-content {
      margin-bottom: 100px;
    }
    .product-delcom {
      color: #323232;
      font-size: 26px;
      border-bottom: 1px solid #EEEEEE;
      padding: 30px 0;
    }
    .product-footerlist {
      margin-top: 10px;
    }
    .product-footerlist li {
      border: 1px solid #606060;
      border-radius: 5px;
      color: #606060;
      text-align: center;
      padding: 10px 30px;
      float: left;
      margin-right: 20px;
      cursor: pointer;
    }
    .product-footerlist li.productActive {
      background-color: #1A1A29;
      color: #fff;
      border: 1px solid #1A1A29;
    }
    .product-footerlist li.noneActive {
      background-color: #ccc;
      opacity: 0.4;
      color: #000;
      pointer-events: none;
    }
    .product-footer {
      background-color: #1A1A29;
      text-align: center;
    }
    .product-footer a {
      color: #fff;
      text-decoration: none;
      height: 88px;
      line-height: 88px;
      font-size: 28px;
    }
    .price{
      font-size: 30px;
      height: 60px;
      line-height: 60px;
    }
  }
</style>

4.最后当然是上效果图了

使用vue实现多规格选择实例(SKU)

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

Javascript 相关文章推荐
通过继承IHttpHandle实现JS插件的组织与管理
Jul 13 Javascript
javascript判断用户浏览器插件安装情况的代码
Jan 01 Javascript
js判断生效时间不得大于失效时间的思路及代码
Apr 23 Javascript
jquery获取所有选中的checkbox实现代码
May 26 Javascript
JS得到当前时间的方法示例
Mar 24 Javascript
微信小程序实现多个按钮toggle功能的实例
Jun 13 Javascript
快速掌握jquery分页插件jqPaginator的使用方法
Aug 09 jQuery
three.js中文文档学习之如何本地运行详解
Nov 20 Javascript
详解VUE2.X过滤器的使用方法
Jan 11 Javascript
JS实现点击下拉菜单把选择的内容同步到input输入框内的实例
Jan 23 Javascript
JavaScript中CreateTextFile函数
Aug 30 Javascript
TypeScript魔法堂之枚举的超实用手册
Oct 29 Javascript
jquery分页优化操作实例分析
Aug 23 #jQuery
jquery实现的分页显示功能示例
Aug 23 #jQuery
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
Aug 22 #Javascript
通过扫小程序码实现网站登陆功能
Aug 22 #Javascript
vue中实现上传文件给后台实例详解
Aug 22 #Javascript
js的新生代垃圾回收知识点总结
Aug 22 #Javascript
JS实现移动端在线签协议功能
Aug 22 #Javascript
You might like
用PHP生成自己的LOG文件
2006/10/09 PHP
php 判断服务器操作系统的类型
2014/02/17 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
2015/01/28 PHP
php中Snoopy类用法实例
2015/06/19 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
javascript读取xml
2006/11/04 Javascript
JQery 渐变图片导航效果代码 漂亮
2010/01/01 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
2015/04/30 Javascript
JavaScript利用Date实现简单的倒计时实例
2017/01/12 Javascript
JavaScript中常见的八个陷阱总结
2017/06/28 Javascript
vue.js实现只弹一次弹框
2018/01/29 Javascript
在 Angular中 使用 Lodash 的方法
2018/02/11 Javascript
简述ES6新增关键字let与var的区别
2019/08/23 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
[18:16]sakonoko 2017年卡尔集锦
2018/02/06 DOTA
python模拟新浪微博登陆功能(新浪微博爬虫)
2013/12/24 Python
python连接字符串的方法小结
2015/07/13 Python
json跨域调用python的方法详解
2017/01/11 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
使用python判断你是青少年还是老年人
2018/11/29 Python
详解Python函数式编程—高阶函数
2019/03/29 Python
Python安装tar.gz格式文件方法详解
2020/01/19 Python
解决python父线程关闭后子线程不关闭问题
2020/04/25 Python
python中判断文件结束符的具体方法
2020/08/04 Python
windows下python 3.9 Numpy scipy和matlabplot的安装教程详解
2020/11/28 Python
python实现xml转json文件的示例代码
2020/12/30 Python
写好自荐信的要点
2013/11/06 职场文书
环境卫生标语
2014/06/09 职场文书
群众路线问题查摆对照检查材料
2014/10/04 职场文书
2014年营业员工作总结
2014/11/18 职场文书
优秀共产党员推荐材料
2014/12/18 职场文书
小学教师见习总结
2015/06/23 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书
go语言中fallthrough的用法说明
2021/05/06 Golang
Redis高并发缓存架构性能优化
2022/05/15 Redis