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


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 相关文章推荐
jquery插件珍藏(图片局部放大/信息提示框)
Jan 08 Javascript
jQuery动态添加删除select项(实现代码)
Sep 03 Javascript
用javascript判断IE版本号简单实用且向后兼容
Sep 11 Javascript
jQuery动态添加、删除元素的方法
Jan 09 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
使用jquery实现IE下按backspace相当于返回操作
Mar 18 Javascript
控制文字内容的显示与隐藏示例
Jun 11 Javascript
javascript获取flash版本号的方法
Nov 20 Javascript
javascript的BOM
May 03 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(1)
Feb 20 Javascript
详解vue.js移动端导航navigationbar的封装
Jul 05 Javascript
使用taro开发微信小程序遇到的坑总结
Apr 08 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
5.PHP的其他功能
2006/10/09 PHP
常用的php ADODB使用方法集锦
2008/03/25 PHP
用php实现的下载css文件中的图片的代码
2010/02/08 PHP
php单例模式实现(对象只被创建一次)
2012/12/05 PHP
PHP取余函数介绍MOD(x,y)与x%y
2014/05/15 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
php使用parse_str实现查询字符串解析到变量中的方法
2017/02/17 PHP
php分页查询mysql结果的base64处理方法示例
2017/05/18 PHP
基础的prototype.js常用函数及其用法
2007/03/10 Javascript
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
2010/01/15 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
Extjs的FileUploadField文件上传出现了两个上传按钮
2014/04/29 Javascript
jQuery学习笔记之jQuery原型属性和方法
2014/06/09 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
2016/08/19 Javascript
基于jquery日历价格、库存等设置插件
2020/07/05 jQuery
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
js实现购物车功能
2018/06/12 Javascript
使用vue的transition完成滑动过渡的示例代码
2018/06/25 Javascript
vue使用laydate时间插件的方法
2018/11/14 Javascript
利用React Router4实现的服务端直出渲染(SSR)
2019/01/07 Javascript
Python中__call__用法实例
2014/08/29 Python
python中print的不换行即时输出的快速解决方法
2016/07/20 Python
Python中将字典转换为列表的方法
2016/09/21 Python
numpy自动生成数组详解
2017/12/15 Python
matplotlib subplots 调整子图间矩的实例
2018/05/25 Python
Html5之自定义属性(data-,dataset)
2019/11/19 HTML / CSS
京东港澳售:京东直邮港澳台
2018/01/31 全球购物
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
消防安全检查制度
2014/02/04 职场文书
新任教师自我鉴定
2014/02/24 职场文书
学校火灾防控方案
2014/06/09 职场文书
大学生作弊检讨书
2014/09/11 职场文书
2015年禁毒宣传活动总结
2015/03/25 职场文书
工作态度检讨书范文
2015/05/06 职场文书
vue使用v-model进行跨组件绑定的基本实现方法
2021/04/28 Vue.js
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS