使用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.ajax 用户登录验证代码
Oct 29 Javascript
JS中showModalDialog 的使用解析
Apr 17 Javascript
jquery判断小数点两位和自动删除小数两位后的数字
Mar 19 Javascript
javascript实现图像循环明暗变化的方法
Feb 25 Javascript
javascript解决IE6下hover问题的方法
Jul 28 Javascript
原生JS实现图片轮播切换效果
Dec 15 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
May 22 Javascript
用JS实现简单的登录验证功能
Jul 28 Javascript
微信小程序实现tab页面切换功能
Jul 13 Javascript
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
Aug 17 Javascript
JS面向对象编程实现的Tab选项卡案例详解
Mar 03 Javascript
基于jQuery拖拽事件的封装
Nov 29 jQuery
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
Snoopy类使用小例子
2008/04/15 PHP
php中对2个数组相加的函数
2011/06/24 PHP
『PHP』PHP截断函数mb_substr()使用介绍
2013/04/22 PHP
php设计模式之单例模式代码
2016/06/11 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
PHP实现基于面向对象的mysqli扩展库增删改查操作工具类
2017/07/18 PHP
PHP判断函数是否被定义的方法
2019/06/21 PHP
解决window.opener=null;window.close(),只支持IE6不支持IE7,IE8的问题
2014/01/14 Javascript
jQuery功能函数详解
2015/02/01 Javascript
JS+CSS实现仿新浪微博搜索框的方法
2015/02/24 Javascript
分享10个原生JavaScript技巧
2015/04/20 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
2015/10/23 Javascript
每天一篇javascript学习小结(String对象)
2015/11/18 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
javascript验证内容为数字以及长度为10的简单实例
2016/08/20 Javascript
javascript 闭包详解及简单实例应用
2016/12/31 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
gulp加批处理(.bat)实现ng多应用一键自动化构建
2017/02/16 Javascript
jQuery模拟淘宝购物车功能
2017/02/27 Javascript
Vue.js实战之组件之间的数据传递
2017/04/01 Javascript
JS+CSS实现网页加载中的动画效果
2017/10/27 Javascript
基于JSONP原理解析(推荐)
2017/12/04 Javascript
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
2018/10/12 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
koa中间件核心(koa-compose)源码解读分析
2020/06/15 Javascript
[02:49:21]2019完美盛典全程录像
2019/12/08 DOTA
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
python实现k均值算法示例(k均值聚类算法)
2014/03/16 Python
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
2014/07/18 Python
python访问mysql数据库的实现方法(2则示例)
2016/01/06 Python
Python 装饰器实现DRY(不重复代码)原则
2018/03/05 Python
python之Flask实现简单登录功能的示例代码
2018/12/24 Python
python文件操作的简单方法总结
2019/11/07 Python
军训拉歌口号
2014/06/13 职场文书
妈妈别哭观后感
2015/06/08 职场文书
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
2021/11/27 Vue.js