所提及的购物数量的加减,现在说说商品属性值联动选择。

为了让同学们有个直观的了解,到电商网截了一个图片,就是红圈所示的部分

现在就为大家介绍这个小组件,在小程序中,该如何去写

下图为本项目的图:

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:;
}

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
})
}
}
})

运行效果:

微信小程序之商品属性分类的更多相关文章

  1. 微信小程序实现watch属性监听数据变化

    Vue 提供了一种通用的方式来观察和响应 Vue 实例上的数据变动:监听属性 watch. 虽然watch的滥用会导致性能不佳,但在一些情况下我们还是需要watch,使得代码更加简洁.逻辑更加清晰(其 ...

  2. 微信小程序转发商品的详情页 + 转发功能(传参)

    1.微信小程序转发传参,利用的还是onShareAppMessageapi 2.利用的还有json转换 JSON 是用于存储和传输数据的格式. JSON 通常用于服务端向网页传递数据 函数 描述JSO ...

  3. 微信小程序之商品发布+编辑功能(多图片上传功能)

    小程序的商品发布页面:功能有多图片上传 遇到的问题记录一下:1.uploadFile成功之后返回的参数是json字符串,一定要用JSON.parse转换为object格式 2.因为商品发布和编辑都是在 ...

  4. 微信小程序多商品评价评星提交

    <form bindsubmit="submitComment"> <block wx:for="{{commentList}}" wx:ke ...

  5. 解决微信小程序Video 某些属性设置不起作用问题

    <video controls="{{false}}" autoplay="{{true}}"></video> 设置属性务必要使用{{ ...

  6. 微信小程序flex容器属性详解

    flex容器属性详解 flex-direction决定元素的排列方向 flex-wrap决定元素如何换行 flex-flow 是 flex-direction 和flex-wrap的简写 justif ...

  7. 微信小程序 仿‘得到app’分类列表页

    今天另起一篇,贴出完整的代码,大概思路是左侧大分类列表,点击后联动右侧二级分类,及下面文章列表,点击二级分类也联动下面文章列表. 代码如下: <view class="page&quo ...

  8. 微信小程序 | flex布局属性

    flex-direction 主轴方向 row: 横向 row-reverse: 横向倒序 column: 纵向 column-reverse: 纵向倒序; flex-wrap 元素排列换行 nowr ...

  9. 微信小程序教程系列

    微信小程序教程系列 来源:       https://blog.csdn.net/michael_ouyang/article/details/56846185 相关连接:http://blog.c ...

随机推荐

  1. iOS开发RunLoop学习:四:RunLoop的应用和RunLoop的面试题

    一:RunLoop的应用 #import "ViewController.h" @interface ViewController () /** 注释 */ @property ( ...

  2. 【u245】机房病毒

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 我们机房中了病毒,因此几乎什么都无法正常进入.为了解决这个病毒,我们花了好几天.终于在大家的共同努力下 ...

  3. mui常用功能链接地址

    1.下拉刷新mui.pullToRefresh插件http://ask.dcloud.net.cn/article/12152.打包app权限列表http://ask.dcloud.net.cn/ar ...

  4. PatentTips - Hardware virtualization such as separation kernel hypervisors

    BACKGROUND 1. Field Innovations herein pertain to computer virtualization, computer security and/or ...

  5. Android推送进阶课程学习笔记

    今天在慕课网学习了Android进阶课程推送的server端处理回执的消息 . 这集课程主要介绍了,当server往client推送消息的时候,client须要发送一个回执回来确认收到了推送消息才算一 ...

  6. nopCommerce 3.9 接口笔记

    接口笔记 Nop.Services.Configuration ISettingService : 配置接口(查看) Nop.Services.Localization ILocalizationSe ...

  7. JS实现鼠标经过用户头像显示资料卡的效果,可点击

    基于项目的须要.须要制作出例如以下的一种页面效果:当用户鼠标经过好友列表中好友头像时,显示该好友的基本资料.事实上也就是类似QQclient的那种功能. 网上找了非常多代码,基本都实现了鼠标悬浮之后弹 ...

  8. 学习鸟哥的Linux私房菜笔记(6)——过滤器、输入输出及管道

    一.过滤器 Linux中的应用工具分为三种: 交互工具 过滤器 编辑器 能够接受数据,过滤再输出的工具,称之为过滤器 对过滤器和进程,存在着输入源与输出对象 二.输入.输出.重定向 输入:过滤器的数据 ...

  9. 【BZOJ 1014】 [JSOI2008]火星人prefix

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 让你在线查询最长公共前缀. 支持单节点修改; 插入操作; [题解] / ...

  10. Qt的paint函数重写,以及QPaint给一条线绘制箭头

    直接代码: QPainter *painter; static const double Pi = 3.14159265358979323846264338327950288419717; stati ...