微信小程序商城項(xiàng)目之商品屬性分類(4)
續(xù)上一篇的文章:微信小程序之購(gòu)物數(shù)量加減 —— 微信小程序?qū)崙?zhàn)商城系列(3)
所提及的購(gòu)物數(shù)量的加減,現(xiàn)在說(shuō)說(shuō)商品屬性值聯(lián)動(dòng)選擇。
為了讓同學(xué)們有個(gè)直觀的了解,到電商網(wǎng)截了一個(gè)圖片,就是紅圈所示的部分

現(xiàn)在就為大家介紹這個(gè)小組件,在小程序中,該如何去寫
下圖為本項(xiàng)目的圖:

wxml:
<view class="title">商品屬性值聯(lián)動(dòng)選擇</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">
<!--每個(gè)屬性值-->
<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;
}
/*每個(gè)屬性值*/
.attr_value {
float: left;
padding: 0 10rpx;
margin: 0 10rpx;
border: 1rpx solid #ececec;
}
/*每個(gè)屬性選中的當(dāng)前樣式*/
.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:
數(shù)據(jù)部分,一般情況都是訪問(wèn)接口獲取數(shù)據(jù)的,這里并沒有使用網(wǎng)絡(luò)訪問(wèn),為了簡(jiǎn)化demo,直接把一組數(shù)據(jù)放在data對(duì)象中。
Page({
data: {
firstIndex: -1,
//準(zhǔn)備數(shù)據(jù)
//數(shù)據(jù)結(jié)構(gòu):以一組一組來(lái)進(jìn)行設(shè)定
commodityAttr: [
{
priceId: 1,
price: 35.0,
"stock": 8,
"attrValueList": [
{
"attrKey": "型號(hào)",
"attrValue": "2"
},
{
"attrKey": "顏色",
"attrValue": "白色"
},
{
"attrKey": "大小",
"attrValue": "小"
},
{
"attrKey": "尺寸",
"attrValue": "S"
}
]
},
{
priceId: 2,
price: 35.1,
"stock": 9,
"attrValueList": [
{
"attrKey": "型號(hào)",
"attrValue": "1"
},
{
"attrKey": "顏色",
"attrValue": "黑色"
},
{
"attrKey": "大小",
"attrValue": "小"
},
{
"attrKey": "尺寸",
"attrValue": "M"
}
]
},
{
priceId: 3,
price: 35.2,
"stock": 10,
"attrValueList": [
{
"attrKey": "型號(hào)",
"attrValue": "1"
},
{
"attrKey": "顏色",
"attrValue": "綠色"
},
{
"attrKey": "大小",
"attrValue": "大"
},
{
"attrKey": "尺寸",
"attrValue": "L"
}
]
},
{
priceId: 4,
price: 35.2,
"stock": 10,
"attrValueList": [
{
"attrKey": "型號(hào)",
"attrValue": "1"
},
{
"attrKey": "顏色",
"attrValue": "綠色"
},
{
"attrKey": "大小",
"attrValue": "大"
},
{
"attrKey": "尺寸",
"attrValue": "L"
}
]
}
],
attrValueList: []
},
onShow: function () {
this.setData({
includeGroup: this.data.commodityAttr
});
this.distachAttrValue(this.data.commodityAttr);
// 只有一個(gè)屬性組合的時(shí)候默認(rèn)選中
// 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
});
}
},
/* 獲取數(shù)據(jù) */
distachAttrValue: function (commodityAttr) {
/**
將后臺(tái)返回的數(shù)據(jù)組合成類似
{
attrKey:'型號(hào)',
attrValueList:['1','2','3']
}
*/
// 把數(shù)據(jù)對(duì)象的數(shù)據(jù)(視圖使用),寫到局部?jī)?nèi)
var attrValueList = this.data.attrValueList;
// 遍歷獲取的數(shù)據(jù)
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,此時(shí)新增屬性并設(shè)置屬性值數(shù)組的第一個(gè)值;索引大于等于0,表示已存在的屬性名的位置
if (attrIndex >= 0) {
// 如果屬性值數(shù)組中沒有該值,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) {
// 判斷數(shù)組中的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) {
/*
點(diǎn)選屬性值,聯(lián)動(dòng)判斷其他屬性值是否可選
{
attrKey:'型號(hào)',
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) { // 如果是第一個(gè)選中的屬性值,則該屬性所有值可選
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('結(jié)果', 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);
}
}
},
/* 點(diǎn)擊確定 */
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: '請(qǐng)完善屬性',
icon: 'loading',
duration: 1000
})
} else {
wx.showToast({
title: '選擇的屬性:' + value.join('-'),
icon: 'sucess',
duration: 1000
})
}
}
}) 運(yùn)行效果:

demo地址:微信小程序商城項(xiàng)目之商品屬性值聯(lián)動(dòng)選擇
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js 實(shí)現(xiàn)css風(fēng)格選擇器(壓縮后2KB)
近日在做一些OA前端界面,為了更好管理頁(yè)面代碼想寫個(gè)js選擇器,寫著寫著發(fā)現(xiàn)很費(fèi)力,索性在網(wǎng)上找找看,功夫不負(fù)有心人, 找到一個(gè)mini css選擇器,且性能不凡:以下代碼是壓縮后的,僅2KB2012-01-01
three.js實(shí)現(xiàn)3D影院的原理的代碼分析
本篇文章主要給大家講解了如何通過(guò)three.js實(shí)現(xiàn)3D影院的功能以及原理分析,需要的朋友參考一下吧。2017-12-12
jsonp的簡(jiǎn)單介紹以及其安全風(fēng)險(xiǎn)
JSONP原理就是動(dòng)態(tài)插入帶有跨域url的script標(biāo)簽,然后調(diào)用回調(diào)函數(shù),把我們需要的json數(shù)據(jù)作為參數(shù)傳入,通過(guò)一些邏輯把數(shù)據(jù)顯示在頁(yè)面上,這篇文章主要給大家介紹了關(guān)于jsonp的簡(jiǎn)單介紹以及其安全風(fēng)險(xiǎn)的相關(guān)資料,需要的朋友可以參考下2022-01-01
JavaScript實(shí)現(xiàn)日期格式化詳細(xì)實(shí)例
這篇文章主要給大家介紹了關(guān)于JavaScript實(shí)現(xiàn)日期格式化的相關(guān)資料,JavaScript中的日期對(duì)象提供了許多方法和屬性,可以通過(guò)它們來(lái)進(jìn)行日期的格式化,需要的朋友可以參考下2023-09-09
關(guān)于原生js中bind函數(shù)的簡(jiǎn)單實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇關(guān)于原生js中bind函數(shù)的簡(jiǎn)單實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
bootstrap+jQuery實(shí)現(xiàn)的動(dòng)態(tài)進(jìn)度條功能示例
這篇文章主要介紹了bootstrap+jQuery實(shí)現(xiàn)的動(dòng)態(tài)進(jìn)度條功能,結(jié)合完整實(shí)例形式分析了bootstrap+jQuery實(shí)現(xiàn)動(dòng)態(tài)進(jìn)度條的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
JavaScript 精美貪吃蛇實(shí)現(xiàn)流程
看起來(lái)好像很復(fù)雜的貪吃蛇,到底是怎么用JavaScript去實(shí)現(xiàn)的?下面就來(lái)一步一步地,剖析怎么用JavaScript,放在任意一個(gè)瀏覽器中,把貪吃蛇搞起來(lái)2021-11-11

