使用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 相关文章推荐
jquery自定义属性(类型/属性值)
May 21 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
Dec 26 Javascript
javascript实现文本域写入字符时限定字数
Feb 12 Javascript
javascript/jquery获取地址栏url参数的方法
Mar 05 Javascript
jQuery 插件封装的方法
Nov 16 Javascript
JS实现unicode和UTF-8之间的互相转换互转
Jul 05 Javascript
微信小程序url与token设置详解
Sep 26 Javascript
解决eclipse中没有js代码提示的问题
Oct 10 Javascript
vue自定义指令用法经典实例小结
Mar 16 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
Sep 27 Javascript
Javascript基于OOP实实现探测器功能代码实例
Aug 26 Javascript
原生js实现自定义滚动条
Jan 20 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
第十一节 重载 [11]
2006/10/09 PHP
php zend解密软件绿色版测试可用
2008/04/14 PHP
PHP实现微信提现(企业付款到零钱)
2019/08/01 PHP
IE中直接运行显示当前网页中的图片 推荐
2006/08/31 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
如何将一个String和多个String值进行比较思路分析
2013/04/22 Javascript
javascript中的作用域和上下文使用简要概述
2013/12/05 Javascript
js获取窗口相对于屏幕左边和上边的位置坐标
2014/05/15 Javascript
Javascript基础_嵌入图像的简单实现
2016/06/14 Javascript
使用JQuery选择HTML遍历函数的方法
2016/09/17 Javascript
详解JavaScript模块化开发
2016/12/04 Javascript
Node.js中如何合并两个复杂对象详解
2016/12/31 Javascript
Angular2学习教程之TemplateRef和ViewContainerRef详解
2017/05/25 Javascript
浅谈ajax请求不同页面的微信JSSDK问题
2018/02/26 Javascript
JS实现数组深拷贝的方法分析
2019/03/06 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
jquery实现鼠标悬浮弹出气泡提示框
2020/12/23 jQuery
[01:00]选手抵达华西村 整装待发备战2016国际邀请赛中国区预选赛
2016/06/25 DOTA
python基于xmlrpc实现二进制文件传输的方法
2015/06/02 Python
python获取外网IP并发邮件的实现方法
2017/10/01 Python
python版本的仿windows计划任务工具
2018/04/30 Python
jupyter notebook 中输出pyecharts图实例
2020/04/23 Python
python实现拉普拉斯特征图降维示例
2019/11/25 Python
如何查看Django ORM执行的SQL语句的实现
2020/04/20 Python
什么是Python包的循环导入
2020/09/08 Python
Html5之svg可缩放矢量图形_动力节点Java学院整理
2017/07/17 HTML / CSS
突袭HTML5之Javascript API扩展3—本地存储全新体验
2013/01/31 HTML / CSS
工作的心得体会
2013/12/31 职场文书
创业计划书怎样才能打动风投
2014/01/01 职场文书
学习决心书
2014/03/11 职场文书
业务员辞职信范文
2015/03/02 职场文书
校园环境卫生倡议书
2015/04/29 职场文书
工作证明书
2015/06/15 职场文书
护士工作心得体会
2016/01/25 职场文书
MySQL 覆盖索引的优点
2021/05/19 MySQL
Python+Matplotlib+LaTeX玩转数学公式
2022/02/24 Python