本期的微信小程序實戰篇來作一個電商網站常常用到的-商品屬性聯動選擇的效果,素材參考了一點點奶茶。小程序
商品屬性聯動.gif微信小程序
<!-- <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:提交校驗並獲取選中商品屬性結果。數組
數據結構微信
//數據結構:以一組一組的數據來進行設定 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); } }
.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