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


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 相关文章推荐
使用JavaScript库还是自己写代码?
Jan 28 Javascript
几个有趣的Javascript Hack
Jul 24 Javascript
JavaScript中使用document.write向页面输出内容实例
Oct 16 Javascript
浅析jQuery EasyUI中的tree使用指南
Dec 18 Javascript
在浏览器中实现图片粘贴的jQuery插件-- pasteimg使用指南
Dec 29 Javascript
JavaScript获取网页中第一个链接ID的方法
Apr 03 Javascript
在JavaScript中使用开平方根的sqrt()方法
Jun 15 Javascript
javascript实现的闭包简单实例
Jul 17 Javascript
jQuery插件ContextMenu自定义图标
Mar 15 Javascript
浅谈Vue的响应式原理
May 30 Javascript
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 Javascript
vue+element UI实现树形表格
Dec 29 Vue.js
微信小程序实现购物页面左右联动
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设计模式之简单工厂模式详解
2014/09/04 PHP
php仿微信红包分配算法的实现方法
2016/05/13 PHP
用JavaScript获取网页中的js、css、Flash等文件
2006/12/20 Javascript
jquery插件validate验证的小例子
2013/05/08 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
Backbone中View之间传值的学习心得
2016/08/09 Javascript
Radio 单选JS动态添加的选项onchange事件无效的解决方法
2016/12/12 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
2017/05/08 jQuery
React/Redux应用使用Async/Await的方法
2017/11/16 Javascript
Angular实现搜索框及价格上下限功能
2018/01/19 Javascript
JavaScript使用math.js进行精确计算操作示例
2018/06/19 Javascript
Three.js实现3D机房效果
2018/12/30 Javascript
JS通过ajax + 多列布局 + 自动加载实现瀑布流效果
2019/05/30 Javascript
使用 Vue 实现一个虚拟列表的方法
2019/08/20 Javascript
Python内置数据结构与操作符的练习题集锦
2016/07/01 Python
python实现自主查询实时天气
2018/06/22 Python
python3实现表白神器
2019/04/09 Python
python对csv文件追加写入列的方法
2019/08/01 Python
详解用python生成随机数的几种方法
2019/08/04 Python
python打印异常信息的两种实现方式
2019/12/24 Python
Xadmin+rules实现多选行权限方式(级联效果)
2020/04/07 Python
html5 拖拽上传图片实例演示
2013/04/01 HTML / CSS
美国购买隐形眼镜网站:Lenses For Less
2020/07/05 全球购物
岗位竞聘演讲稿
2014/01/10 职场文书
新学期班主任寄语
2014/01/18 职场文书
初一新生军训方案
2014/05/22 职场文书
药品营销策划方案
2014/06/15 职场文书
银行稽核岗位职责
2015/04/13 职场文书
2019财务转正述职报告
2019/06/27 职场文书
详解Python小数据池和代码块缓存机制
2021/04/07 Python
Python3中最常用的5种线程锁实例总结
2021/07/07 Python
HTML5 语义化标签(移动端必备)
2021/08/23 HTML / CSS
深入浅出的讲解:信号调制到底是如何实现的
2022/02/18 无线电
Redis中有序集合的内部实现方式的详细介绍
2022/03/16 Redis
Linux服务器离线安装 nginx的详细步骤
2022/06/16 Servers
2022年显卡天梯图(6月更新)
2022/06/17 数码科技