微信小程序实现商品属性联动选择


Posted in Javascript onFebruary 15, 2019

本文实例为大家分享了微信小程序实现商品属性联动选择的具体代码,供大家参考,具体内容如下

效果演示:

微信小程序实现商品属性联动选择

代码示例

1、commodity.xml

<!-- <view class="title">属性值联动选择</view>  -->
<!--options-->
<view class="commodity_attr_list"> 
  <!--每组属性-->
  <view class="attr_box" wx:for="{{attrValueList}}" wx:for-item="attrValueObj" wx:for-index="attrIndex"> 
   <!--属性名-->
   <view class="attr_name">{{attrValueObj.attrKey}}</view> 
 
   <!--属性值-->
   <view class="attr_value_box"> 
     <!--每个属性值-->
     <view class="attr_value {{attrIndex==firstIndex || attrValueObj.attrValueStatus[valueIndex]?(value==attrValueObj.selectedValue?'attr_value_active':''):'attr_value_disabled'}}" bindtap="selectAttrValue" data-status="{{attrValueObj.attrValueStatus[valueIndex]}}"
     data-value="{{value}}" data-key="{{attrValueObj.attrKey}}" data-code="{{attrCode}}" data-index="{{attrIndex}}" data-selectedvalue="{{attrValueObj.selectedValue}}" wx:for="{{attrValueObj.attrValues}}" wx:for-item="value" wx:for-index="valueIndex">{{value}}</view> 
   </view> 
 </view> 
</view> 
<!--button-->
<view class="weui-btn-area"> 
  <button class="weui-btn" bindtap="submit">选好了    </button> 
</view>

上述代码把页面盒子分为两部分commodity_attr_list和weui-btn-area。
commodity_attr_list:循环获取商品的属性名和相对应的属性值,并布局页面。
weui-btn-area:提交校验并获取选中商品属性结果。

2、commodity.js

数据结构

//数据结构:以一组一组的数据来进行设定 
  commodityAttr: [
   {
    priceId: 1,
    price: 35.0,
    "stock": 8,
    "attrValueList": [
     {
      "attrKey": "规格:",
      "attrValue": "+免费配料",
      "attrCode": "1001"
     },
     {
      "attrKey": "甜度:",
      "attrValue": "七分甜",
      "attrCode": "2001"
     },
     {
      "attrKey": "加料:",
      "attrValue": "珍珠",
      "attrCode": "3001"
     },
     {
      "attrKey": "冰块:",
      "attrValue": "少冰",
      "attrCode": "4001"
     }
    ]
   },
   {
    priceId: 2,
    price: 35.1,
    "stock": 9,
    "attrValueList": [
     {
      "attrKey": "规格:",
      "attrValue": "+燕麦",
      "attrCode": "1002"
     },
     {
      "attrKey": "甜度:",
      "attrValue": "五分甜",
      "attrCode": "2002"
     },
     {
      "attrKey": "加料:",
      "attrValue": "椰果",
      "attrCode": "3002"
     },
     {
      "attrKey": "冰块:",
      "attrValue": "去冰",
      "attrCode": "4002"
     }
    ]
   },
   {
    priceId: 3,
    price: 35.2,
    "stock": 10,
    "attrValueList": [
     {
      "attrKey": "规格:",
      "attrValue": "+布丁",
      "attrCode": "1003"
     },
     {
      "attrKey": "甜度:",
      "attrValue": "无糖",
      "attrCode": "2003"
     },
     {
      "attrKey": "加料:",
      "attrValue": "仙草",
      "attrCode": "3003"
     },
     {
      "attrKey": "冰块:",
      "attrValue": "常温",
      "attrCode": "4003"
     }
    ]
   },
   {
    priceId: 4,
    price: 35.2,
    "stock": 10,
    "attrValueList": [
     {
      "attrKey": "规格:",
      "attrValue": "再加一份奶霜",
      "attrCode": "1004"
     },
     {
      "attrKey": "甜度:",
      "attrValue": "无糖",
      "attrCode": "2003"
     },
     {
      "attrKey": "加料:",
      "attrValue": "仙草",
      "attrCode": "3004"
     },
     {
      "attrKey": "冰块:",
      "attrValue": "热饮",
      "attrCode": "4004"
     }
    ]
   },
   {
    priceId: 5,
    price: 35.2,
    "stock": 10,
    "attrValueList": [
     {
      "attrKey": "规格:",
      "attrValue": "+免费配料",
      "attrCode": "1004"
     },
     {
      "attrKey": "甜度:",
      "attrValue": "五分甜",
      "attrCode": "2003"
     },
     {
      "attrKey": "加料:",
      "attrValue": "椰果",
      "attrCode": "3004"
     },
     {
      "attrKey": "冰块:",
      "attrValue": "常温",
      "attrCode": "4004"
     }
    ]
   }
  ],
  attrValueList: []
 }

属性选中和取消选择效果处理

onShow: function () {
  this.setData({
   includeGroup: this.data.commodityAttr
  });
  this.distachAttrValue(this.data.commodityAttr);
  // 只有一个属性组合的时候默认选中 
  // console.log(this.data.attrValueList); 
  if (this.data.commodityAttr.length == 1) {
   for (var i = 0; i < this.data.commodityAttr[0].attrValueList.length; i++) {
    this.data.attrValueList[i].selectedValue = this.data.commodityAttr[0].attrValueList[i].attrValue;
   }
   this.setData({
    attrValueList: this.data.attrValueList
   });
  }
 },
 /* 获取数据 */
 distachAttrValue: function (commodityAttr) {
  /** 
  将后台返回的数据组合成类似 
  { 
  attrKey:'型号', 
  attrValueList:['1','2','3'] 
  } 
  */
  // 把数据对象的数据(视图使用),写到局部内 
  var attrValueList = this.data.attrValueList;
  // 遍历获取的数据 
  for (var i = 0; i < commodityAttr.length; i++) {
   for (var j = 0; j < commodityAttr[i].attrValueList.length; j++) {
    var attrIndex = this.getAttrIndex(commodityAttr[i].attrValueList[j].attrKey, attrValueList);
    // console.log('属性索引', attrIndex); 
    // 如果还没有属性索引为-1,此时新增属性并设置属性值数组的第一个值;索引大于等于0,表示已存在的属性名的位置 
    if (attrIndex >= 0) {
     // 如果属性值数组中没有该值,push新值;否则不处理 
     if (!this.isValueExist(commodityAttr[i].attrValueList[j].attrValue, attrValueList[attrIndex].attrValues)) {
      attrValueList[attrIndex].attrValues.push(commodityAttr[i].attrValueList[j].attrValue);
     }
    } else {
     attrValueList.push({
      attrKey: commodityAttr[i].attrValueList[j].attrKey,
      attrValues: [commodityAttr[i].attrValueList[j].attrValue]
     });
    }
   }
  }
  // console.log('result', attrValueList) 
  for (var i = 0; i < attrValueList.length; i++) {
   for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
    if (attrValueList[i].attrValueStatus) {
     attrValueList[i].attrValueStatus[j] = true;
    } else {
     attrValueList[i].attrValueStatus = [];
     attrValueList[i].attrValueStatus[j] = true;
    }
   }
  }
  this.setData({
   attrValueList: attrValueList
  });
 },
 getAttrIndex: function (attrName, attrValueList) {
  // 判断数组中的attrKey是否有该属性值 
  for (var i = 0; i < attrValueList.length; i++) {
   if (attrName == attrValueList[i].attrKey) {
    break;
   }
  }
  return i < attrValueList.length ? i : -1;
 },
 isValueExist: function (value, valueArr) {
  // 判断是否已有属性值 
  for (var i = 0; i < valueArr.length; i++) {
   if (valueArr[i] == value) {
    break;
   }
  }
  return i < valueArr.length;
 },
 /* 选择属性值事件 */
 selectAttrValue: function (e) {
  /* 
  点选属性值,联动判断其他属性值是否可选 
  { 
  attrKey:'型号', 
  attrValueList:['1','2','3'], 
  selectedValue:'1', 
  attrValueStatus:[true,true,true] 
  } 
  console.log(e.currentTarget.dataset); 
  */
  var attrValueList = this.data.attrValueList;
  var index = e.currentTarget.dataset.index;//属性索引 
  var key = e.currentTarget.dataset.key;
  var value = e.currentTarget.dataset.value;
  if (e.currentTarget.dataset.status || index == this.data.firstIndex) {
   if (e.currentTarget.dataset.selectedvalue == e.currentTarget.dataset.value) {
    // 取消选中 
    this.disSelectValue(attrValueList, index, key, value);
   } else {
    // 选中 
    this.selectValue(attrValueList, index, key, value);
   }
 
  }
 },
 /* 选中 */
 selectValue: function (attrValueList, index, key, value, unselectStatus) {
  // console.log('firstIndex', this.data.firstIndex); 
  var includeGroup = [];
  if (index == this.data.firstIndex && !unselectStatus) { // 如果是第一个选中的属性值,则该属性所有值可选 
   var commodityAttr = this.data.commodityAttr;
   // 其他选中的属性值全都置空 
   // console.log('其他选中的属性值全都置空', index, this.data.firstIndex, !unselectStatus); 
   for (var i = 0; i < attrValueList.length; i++) {
    for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
     attrValueList[i].selectedValue = '';
    }
   }
  } else {
   var commodityAttr = this.data.includeGroup;
  }
 
  // console.log('选中', commodityAttr, index, key, value); 
  for (var i = 0; i < commodityAttr.length; i++) {
   for (var j = 0; j < commodityAttr[i].attrValueList.length; j++) {
    if (commodityAttr[i].attrValueList[j].attrKey == key && commodityAttr[i].attrValueList[j].attrValue == value) {
     includeGroup.push(commodityAttr[i]);
    }
   }
  }
  attrValueList[index].selectedValue = value;
 
  // 判断属性是否可选 
  for (var i = 0; i < attrValueList.length; i++) {
   for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
    attrValueList[i].attrValueStatus[j] = false;
   }
  }
  for (var k = 0; k < attrValueList.length; k++) {
   for (var i = 0; i < includeGroup.length; i++) {
    for (var j = 0; j < includeGroup[i].attrValueList.length; j++) {
     if (attrValueList[k].attrKey == includeGroup[i].attrValueList[j].attrKey) {
      for (var m = 0; m < attrValueList[k].attrValues.length; m++) {
       if (attrValueList[k].attrValues[m] == includeGroup[i].attrValueList[j].attrValue) {
        attrValueList[k].attrValueStatus[m] = true;
       }
      }
     }
    }
   }
  }
  // console.log('结果', attrValueList); 
  this.setData({
   attrValueList: attrValueList,
   includeGroup: includeGroup
  });
 
  var count = 0;
  for (var i = 0; i < attrValueList.length; i++) {
   for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
    if (attrValueList[i].selectedValue) {
     count++;
     break;
    }
   }
  }
  if (count < 2) {// 第一次选中,同属性的值都可选 
   this.setData({
    firstIndex: index
   });
  } else {
   this.setData({
    firstIndex: -1
   });
  }
 },
 /* 取消选中 */
 disSelectValue: function (attrValueList, index, key, value) {
  var commodityAttr = this.data.commodityAttr;
  attrValueList[index].selectedValue = '';
 
  // 判断属性是否可选 
  for (var i = 0; i < attrValueList.length; i++) {
   for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
    attrValueList[i].attrValueStatus[j] = true;
   }
  }
  this.setData({
   includeGroup: commodityAttr,
   attrValueList: attrValueList
  });
 
  for (var i = 0; i < attrValueList.length; i++) {
   if (attrValueList[i].selectedValue) {
    this.selectValue(attrValueList, i, attrValueList[i].attrKey, attrValueList[i].selectedValue, true);
   }
  }
 }

结果提交

submit: function () {
  var value = [];
  for (var i = 0; i < this.data.attrValueList.length; i++) {
   if (!this.data.attrValueList[i].selectedValue) {
    break;
   }
   value.push(this.data.attrValueList[i].selectedValue);
  }
  if (i < this.data.attrValueList.length) {
   wx.showToast({
    title: '请选择完整!',
    icon: 'loading',
    duration: 1000
   })
  } else {
   var valueStr = "";
   for(var i = 0;i < value.length;i++){
    console.log(value[i]);
    valueStr += value[i]+",";
   }
   wx.showModal({
    title: '提示',
    content: valueStr,
    success: function (res) {
     if (res.confirm) {
      console.log('用户点击确定')
     } else if (res.cancel) {
      console.log('用户点击取消')
     }
    }
   }) 
   console.log(valueStr);
  }
 }

3、commodity.wxss

.title { 
 padding: 10rpx 20rpx; 
 margin: 10rpx 0; 
 border-left: 4rpx solid #ccc; 
} 
 
/*全部属性的主盒子*/
.commodity_attr_list { 
 background: #fff; 
 padding: 0 20rpx; 
 font-size: 26rpx; 
 overflow: hidden; 
 width: 100%; 
} 
/*每组属性的主盒子*/
.attr_box { 
 width: 100%; 
 overflow: hidden; 
 border-bottom: 1rpx solid #ececec; 
 display: flex;
 flex-direction: column;
} 
/*属性名*/
.attr_name { 
 width: 20%; 
 float: left; 
 padding: 15rpx 0; 
} 
/*属性值*/
.attr_value_box { 
 width: 80%; 
 float: left; 
 padding: 15rpx 0; 
 overflow: hidden; 
} 
/*每个属性值*/
.attr_value { 
 float: left; 
 padding: 0 30rpx; 
 margin: 10rpx 10rpx; 
 border: 1rpx solid #ececec; 
 border-radius:5px;
 line-height:30px;
} 
/*每个属性选中的当前样式*/
.attr_value_active { 
 border-radius: 10rpx; 
 color: #0089dc; 
 padding: 0 30rpx; 
 border: 1rpx solid #0089dc; 
 /* background: #fff;  */
} 
/*禁用属性*/
.attr_value_disabled { 
 color: #ccc; 
} 
 
/*button*/
.weui-btn-area { 
 margin: 1.17647059em 15px 0.3em; 
} 
.weui-btn{
 width: 80%;
 height: 100rpx;
 border-radius: 3rpx; 
 background-color:#0089dc; 
 color: #fff; 
}

好了,复制上述代码就可以实现效果哦,赶紧试试吧!

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

Javascript 相关文章推荐
js 多浏览器分别判断代码
Apr 01 Javascript
js内置对象 学习笔记
Aug 01 Javascript
js自执行函数的几种不同写法的比较
Aug 16 Javascript
jquery实现控制表格行高亮实例
Jun 05 Javascript
解决Extjs4中form表单提交后无法进入success函数问题
Nov 26 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
Aug 11 Javascript
js简单实现Select互换数据的方法
Aug 17 Javascript
jQuery EasyUI Dialog拖不下来如何解决
Sep 28 Javascript
javascript创建对象、对象继承的实用方式详解
Mar 08 Javascript
node.js 抓取代理ip实例代码
Apr 30 Javascript
Angular.js实现动态加载组件详解
May 28 Javascript
javascript使用正则表达式实现注册登入校验
Sep 23 Javascript
微信小程序实现购物页面左右联动
Feb 15 #Javascript
微信小程序基于picker实现级联菜单
Feb 15 #Javascript
微信小程序实现多个按钮的颜色状态转换
Feb 15 #Javascript
详解react-refetch的使用小例子
Feb 15 #Javascript
小程序实现多列选择器
Feb 15 #Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
Feb 15 #jQuery
微信实现自动跳转到用其他浏览器打开指定APP下载
Feb 15 #Javascript
You might like
php 保留小数点
2009/04/21 PHP
php利用新浪接口查询ip获取地理位置示例
2014/01/20 PHP
twig里使用js变量的方法
2016/02/05 PHP
ECshop 迁移到 PHP7版本时遇到的兼容性问题
2016/02/15 PHP
symfony2.4的twig中date用法分析
2016/03/18 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
详解PHP队列的实现
2019/03/14 PHP
js charAt的使用示例
2014/02/18 Javascript
IE浏览器不支持getElementsByClassName的解决方法
2014/08/27 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
2016/08/11 Javascript
Javascript之面向对象--封装
2016/12/02 Javascript
JS判断指定dom元素是否在屏幕内的方法实例
2017/01/23 Javascript
vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
2017/02/08 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
2017/03/30 Javascript
AngularJS中使用ngModal模态框实例
2017/05/27 Javascript
js实现一个简单的MVVM框架示例
2018/01/15 Javascript
javascript实现数字时钟效果
2021/02/06 Javascript
使用numba对Python运算加速的方法
2018/10/15 Python
浅谈python写入大量文件的问题
2018/11/09 Python
解析python实现Lasso回归
2019/09/11 Python
Pandas操作CSV文件的读写实现方法
2019/11/13 Python
在python中计算ssim的方法(与Matlab结果一致)
2019/12/19 Python
Tensorflow 实现分批量读取数据
2020/01/04 Python
python opencv如何实现图片绘制
2020/01/19 Python
Python基于callable函数检测对象是否可被调用
2020/10/16 Python
Python模块常用四种安装方式
2020/10/20 Python
CSS3 三维变形实现立体方块特效源码
2016/12/15 HTML / CSS
HTML5单选框、复选框、下拉菜单、文本域的实现代码
2020/12/01 HTML / CSS
财务助理岗位职责
2013/11/10 职场文书
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
应届毕业生求职信
2014/05/26 职场文书
班级课外活动总结
2014/07/09 职场文书
村党支部群众路线教育实践活动对照检查材料
2014/09/26 职场文书
会计师事务所实习证明
2014/11/16 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
2015年维修工作总结
2015/04/25 职场文书