使用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 相关文章推荐
可在线编辑网页文字效果代码(单击)
Mar 02 Javascript
解决extjs grid 不随窗口大小自适应的改变问题
Jan 26 Javascript
js实现照片墙功能实例
Feb 05 Javascript
jQuery Ajax 上传文件处理方式介绍(推荐)
Jun 30 Javascript
jQuery实现弹出窗口弹出div层的实例代码
Jan 09 Javascript
ES6生成器用法实例分析
Apr 10 Javascript
神级程序员JavaScript300行代码搞定汉字转拼音
May 20 Javascript
React-Router如何进行页面权限管理的方法
Dec 06 Javascript
Angular实现的table表格排序功能完整示例
Dec 22 Javascript
Angular实现的自定义模糊查询、排序及三角箭头标注功能示例
Dec 28 Javascript
利用js实现前后台传送Json的示例代码
Mar 29 Javascript
JS call()及apply()方法使用实例汇总
Jul 11 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 __autoload()方法真的影响性能吗?
2012/03/30 PHP
对淘宝URL中ID提取的PHP代码
2013/09/01 PHP
thinkphp5实现微信扫码支付
2019/12/23 PHP
动态创建的表格单元格中的事件实现代码
2008/12/30 Javascript
js变换显示图片的实例
2013/04/16 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
jQuery使用attr()方法同时设置多个属性值用法实例
2015/03/26 Javascript
JavaScript中字符串(string)转json的2种方法
2015/06/25 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
js前端面试题及答案整理(一)
2016/08/26 Javascript
老生常谈combobox和combotree模糊查询
2017/04/17 Javascript
小程序实现页面顶部选项卡效果
2018/11/06 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
ES6的异步终极解决方案分享
2019/07/11 Javascript
js模拟F11页面全屏显示
2019/09/17 Javascript
Vue实现渲染数据后控制滚动条位置(推荐)
2019/12/09 Javascript
js实现时钟定时器
2020/03/26 Javascript
[04:37]DOTA2英雄梦之声Vol20发条
2014/06/20 DOTA
Python中使用strip()方法删除字符串中空格的教程
2015/05/20 Python
Python实现的计算器功能示例
2018/04/26 Python
利用python GDAL库读写geotiff格式的遥感影像方法
2018/11/29 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
详解js文件通过python访问数据库方法
2019/03/03 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
对Django外键关系的描述
2019/07/26 Python
numpy矩阵数值太多不能全部显示的解决
2020/05/14 Python
伦敦哈德森鞋:Hudson Shoes
2018/02/06 全球购物
英国在线药房:Express Chemist
2019/03/28 全球购物
北大研究生linux应用求职信
2013/10/29 职场文书
优秀应届毕业生自荐信
2013/11/16 职场文书
外贸专业求职信
2014/03/09 职场文书
表彰大会策划方案
2014/05/13 职场文书
军训心得体会范文(2016最新篇)
2016/01/11 职场文书
教你做个可爱的css滑动导航条
2021/06/15 HTML / CSS
Win10此设备不支持接收Miracast无法投影的解决方法
2022/07/07 数码科技