使用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 隔行换色 支持键盘上下键,按Enter选定值
Aug 02 Javascript
只需20行代码就可以写出CSS覆盖率测试脚本
Apr 24 Javascript
jQuery解决下拉框select设宽度时IE 6/7/8下option超出显示不全
May 27 Javascript
jQuery插件 selectToSelect使用方法
Oct 02 Javascript
使用js操作css实现js改变背景图片示例
Mar 10 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
May 07 Javascript
JS学习之表格的排序简单实例
May 16 Javascript
前端构建工具之gulp的配置与搭建详解
Jun 12 Javascript
基于JavaScript实现淘宝商品广告效果
Aug 10 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
May 04 Javascript
深入理解JavaScript 箭头函数
May 30 Javascript
JS实现京东商品分类侧边栏
Dec 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
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
jquery的ajax异步请求接收返回json数据实例
2014/06/16 Javascript
JavaScript 实现打印,打印预览,打印设置
2014/12/30 Javascript
深入理解JavaScript系列(33):设计模式之策略模式详解
2015/03/03 Javascript
JS实现密码框根据焦点的获取与失去控制文字的消失与显示效果
2015/11/26 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
Bootstrap的fileinput插件实现多文件上传的方法
2016/09/05 Javascript
Ajax使用原生态JS验证用户名是否存在
2020/05/26 Javascript
实现easyui的datagrid导出为excel的示例代码
2016/11/10 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
js设置文字颜色的方法示例
2016/12/30 Javascript
原生js实现返回顶部缓冲效果
2017/01/18 Javascript
jQuery Form插件使用详解_动力节点Java学院整理
2017/07/17 jQuery
vue基于viewer实现的图片查看器功能
2019/04/12 Javascript
浅谈vant组件Picker 选择器选单选问题
2020/11/04 Javascript
浅谈flask截获所有访问及before/after_request修饰器
2018/01/18 Python
python中的单引号双引号区别知识点总结
2019/06/23 Python
使用python绘制cdf的多种实现方法
2020/02/25 Python
Python实现粒子群算法的示例
2021/02/14 Python
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
英国护发和美妆在线商店:Klip Shop
2019/03/24 全球购物
Yummie官方网站:塑身衣和衣柜必需品
2019/10/29 全球购物
.NET面试问题集
2015/12/08 面试题
公司部门司机岗位职责
2014/01/03 职场文书
法学求职信
2014/06/22 职场文书
领导班子四风对照检查材料
2014/09/23 职场文书
学习十八届四中全会依法治国心得体会
2014/11/03 职场文书
2014年学校后勤工作总结
2014/12/06 职场文书
2015年幼儿园新年寄语
2014/12/08 职场文书
请客吃饭开场白
2015/06/01 职场文书
详解如何修改nginx的默认端口
2021/03/31 Servers
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python
Nginx设置HTTPS的方法步骤 443证书配置方法
2022/03/21 Servers
原生JS实现分页
2022/04/19 Javascript
Python 统计序列中元素的出现频度
2022/04/26 Python
Go微服务项目配置文件的定义和读取示例详解
2022/06/21 Golang