微信小程序實戰篇:商品屬性聯動選擇(案例)

圖片


本期的微信小程序實戰篇來作一個電商網站常常用到的-商品屬性聯動選擇的效果,素材參考了一點點奶茶。小程序

效果演示:

圖片

商品屬性聯動.gif微信小程序

代碼示例

一、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_listweui-btn-area
commodity_attr_list:循環獲取商品的屬性名和相對應的屬性值,並佈局頁面。
weui-btn-area:提交校驗並獲取選中商品屬性結果。數組

二、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].attrValue                    List.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);      }    }  }

結果提交app

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);    }  }
三、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; }

好了,複製上述代碼就能夠實現效果哦,趕忙試試吧!xss