微信小程序之商品屬性分類 —— 微信小程序實戰商城系列(4)

續上一篇的文章:微信小程序之購物數量加減 —— 微信小程序實戰商城系列(3)

所提及的購物數量的加減,現在說說商品屬性值聯動選擇。


爲了讓同學們有個直觀的瞭解,到電商網截了一個圖片,就是紅圈所示的部分



現在就爲大家介紹這個小組件,在小程序中,該如何去寫

下圖爲本項目的圖:



wxml

<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-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" type="primary" bindtap="submit">確定</button>
</view>

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;
}
/*屬性名*/
.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 10rpx;
  margin: 0 10rpx;
  border: 1rpx solid #ececec;
}
/*每個屬性選中的當前樣式*/
.attr_value_active {
  background: #FFCC00;
  border-radius: 10rpx;
  color: #fff;
  padding: 0 10rpx;
}
/*禁用屬性*/
.attr_value_disabled {
  color: #ccc;
}

/*button*/
.btn-area {
  margin: 1.17647059em 15px 0.3em;
}

.btn {
  margin-top: 15px;
  background-color:#FFCC00;
  color: #fff;
}
.btn:first-child {
  margin-top: 0;
}

js

數據部分,一般情況都是訪問接口獲取數據的,這裏並沒有使用網絡訪問,爲了簡化demo,直接把一組數據放在data對象中。

Page({
  data: {
    firstIndex: -1,
    //準備數據
    //數據結構:以一組一組來進行設定
    commodityAttr: [
      {
        priceId: 1,
        price: 35.0,
        "stock": 8,
        "attrValueList": [
          {
            "attrKey": "型號",
            "attrValue": "2"
          },
          {
            "attrKey": "顏色",
            "attrValue": "白色"
          },
          {
            "attrKey": "大小",
            "attrValue": "小"
          },
          {
            "attrKey": "尺寸",
            "attrValue": "S"
          }
        ]
      },
      {
        priceId: 2,
        price: 35.1,
        "stock": 9,
        "attrValueList": [
          {
            "attrKey": "型號",
            "attrValue": "1"
          },
          {
            "attrKey": "顏色",
            "attrValue": "黑色"
          },
          {
            "attrKey": "大小",
            "attrValue": "小"
          },
          {
            "attrKey": "尺寸",
            "attrValue": "M"
          }
        ]
      },
      {
        priceId: 3,
        price: 35.2,
        "stock": 10,
        "attrValueList": [
          {
            "attrKey": "型號",
            "attrValue": "1"
          },
          {
            "attrKey": "顏色",
            "attrValue": "綠色"
          },
          {
            "attrKey": "大小",
            "attrValue": "大"
          },
          {
            "attrKey": "尺寸",
            "attrValue": "L"
          }
        ]
      },
      {
        priceId: 4,
        price: 35.2,
        "stock": 10,
        "attrValueList": [
          {
            "attrKey": "型號",
            "attrValue": "1"
          },
          {
            "attrKey": "顏色",
            "attrValue": "綠色"
          },
          {
            "attrKey": "大小",
            "attrValue": "大"
          },
          {
            "attrKey": "尺寸",
            "attrValue": "L"
          }
        ]
      }
    ],
    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 {
      wx.showToast({
        title: '選擇的屬性:' + value.join('-'),
        icon: 'sucess',
        duration: 1000
      })
    }
  }
})

運行效果:



demo地址:http://download.csdn.net/detail/michael_ouyang/9816438

更多小程序的教程


微信開發者工具的快捷鍵

微信小程序的文件結構 —— 微信小程序教程系列(1)

微信小程序的生命週期實例演示 —— 微信小程序教程系列(2)

微信小程序的動態修改視圖層的數據 —— 微信小程序教程系列(3)

微信小程序的新建頁面 —— 微信小程序教程系列(4)

微信小程序的如何使用全局屬性 —— 微信小程序教程系列(5)

微信小程序的頁面跳轉 —— 微信小程序教程系列(6)

微信小程序標題欄和導航欄的設置 —— 微信小程序教程系列(7)

微信小程序的作用域和模塊化 —— 微信小程序教程系列(8)

微信小程序視圖層的數據綁定 —— 微信小程序教程系列(9)

微信小程序視圖層的條件渲染 —— 微信小程序教程系列(10)

微信小程序視圖層的列表渲染 —— 微信小程序教程系列(11)

微信小程序視圖層的模板 —— 微信小程序教程系列(12)

微信小程序wxss的尺寸單位rpx —— 微信小程序教程系列(13)

微信小程序的網絡請求 —— 微信小程序教程系列(14)

微信小程序的百度地圖獲取地理位置 —— 微信小程序教程系列(15)

微信小程序使用百度api獲取天氣信息 —— 微信小程序教程系列(16)

微信小程序獲取系統日期和時間 —— 微信小程序教程系列(17)

微信小程序之頂部導航欄實例 —— 微信小程序實戰系列(1)

微信小程序之上拉加載(分頁加載)實例 —— 微信小程序實戰系列(2)

微信小程序之輪播圖實例 —— 微信小程序實戰系列(3)

微信小程序之仿android fragment之可滑動的底部導航欄實例 —— 微信小程序實戰系列(4)

微信小程序之登錄頁實例 —— 微信小程序實戰系列(5)

微信小程序之自定義toast實例 —— 微信小程序實戰系列(6)

微信小程序之自定義抽屜菜單(從下拉出)實例 —— 微信小程序實戰系列(7)

微信小程序之自定義模態彈窗(帶動畫)實例 —— 微信小程序實戰系列(8)

微信小程序之側欄分類 —— 微信小程序實戰商城系列(1)

微信小程序之仿淘寶分類入口 —— 微信小程序實戰商城系列(2)

微信小程序之購物數量加減 —— 微信小程序實戰商城系列(3)


更多小程序的教程請查看:http://blog.csdn.net/michael_ouyang/article/details/54700871

謝謝觀看,不足之處,敬請指導



發佈了99 篇原創文章 · 獲贊 374 · 訪問量 149萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章