微信小程序商城项目之商品属性分类(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地址:微信小程序商城项目之商品属性值联动选择

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序购物商城系统开发系列-工具篇的介绍

    微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将给予微信小程序进行研发.基于对它的敬畏以及便于大家快速上手,特整理微信小程序商城开发系列,未来将持续增加微信小程序技术文章,让大家可全面了解如何快速开发微信小程序商城. 本篇文章主要介绍微信小程序官方提供的开发工具,俗话说:欲工善其身,必先利其器. 小程序开发文档地址https://mp.weixi

  • 微信小程序商城项目之侧栏分类效果(1)

    在商场项目中,一般都会有分类页面. 分类页面可以给用户快速找到相关的商品,下面以侧栏分类为例,如下图 布局分析: <主盒子> <左盒子></左盒子> <右盒子></右盒子> </主盒子> 左盒子使用标准流 右盒子使用绝对定位(top.right) wxml: <!--主盒子--> <view class="container"> <!--左侧栏--> <view class

  • 微信小程序商城项目之淘宝分类入口(2)

    分类入口,已经成为了商城项目必须的布局之一,这里以仿照淘宝的分类入口来做案例 下图红框部分,就是本文重点讲解部分,另外本文并没有写点击某个入口跳转页面. 如需学习页面跳转的同学,可以参考此文 微信小程序的页面跳转和参数传递 -- 微信小程序教程系列(6) 页面分析: 使用for循环遍历所有项,插入页面,页面中的项使用左浮动,并使用百分比布局,设置20%的宽度每一项. 这样满5个item后,自动排在下一行 wxml: <view class="menu-wrp"> <!

  • 微信小程序购物商城系统开发系列-目录结构介绍

    上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的小demo. 这一篇文章我们主要的是介绍一下小程序的一些目录结构,以及一些语法,为我们后面的微信小程序商城系统做铺垫. 首先我们来了解下小程序的目录结构 Pages 我们新建的一些页面将保存在这个文件夹下面,每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index.js.index.

  • 微信小程序商城项目之购物数量加减(3)

    我们在购买宝贝的时候,购物的数量,经常是我们需要使用的,如下所示: 在宝贝详情页里: 在购物车里: 现在就为大家介绍这个小组件,在小程序中,该如何去写 下图为本项目的图: wxml: <!-- 主容器 --> <view class="stepper"> <!-- 减号 --> <text class="{{minusStatus}}" bindtap="bindMinus">-</text&

  • 微信小程序 商城开发(ecshop )简单实例

    最近小程序特别火,所以我们公司也针对ecshop平台对接了小程序 包括完整的用户系统和购物体统 用户系统:收货地址,订单管理,消息管理,优惠券管理等等 购物系统支付购物车管理,微信支付等等 相信有很多小伙伴都用的是ecshop作为自己的商城,最近小程序又火了,于是就有人问ecshop对接小程序怎么做. 正好最近在开发一个对接ecshop的小程序项目,就将我的一些开发经验分享一下. 一:扫描小程序二维码后的用户信息的获取和缓存 获取用户信息需要用到两个api wx.login(OBJECT) 调用

  • 微信小程序商城项目之商品属性分类(4)

    续上一篇的文章:微信小程序之购物数量加减 -- 微信小程序实战商城系列(3) 所提及的购物数量的加减,现在说说商品属性值联动选择. 为了让同学们有个直观的了解,到电商网截了一个图片,就是红圈所示的部分 现在就为大家介绍这个小组件,在小程序中,该如何去写 下图为本项目的图: wxml: <view class="title">商品属性值联动选择</view> <!--options--> <view class="commodity_a

  • golang实现微信小程序商城后台系统(moshopserver)

    golang和c/c++比起来是一门新的语言,一直想学,网上搜集了一些资料,有些人说很容易上手,确实是这样,和C/C++比起来,少了很多乱七八糟的语法.学一门新的语言,最好的方法就是动手写一些东西,最近小程序也比较火,也想学一下,网络上搜索的一些开源项目,基本上没有golang实现的,大部分都是nodejs和java写的,那么我就来实现一个golang版的吧,一石二鸟. 开发小程序前后端都需要开发,自己的前端经验很少,搜索了一些开源代码,有一个小程序项目让人眼前一亮,Nideshop,界面做的不

  • 微信小程序实战项目之富文本编辑器实现

    目录 前言 1. 实现效果 2. 创建发布页面,实现基本布局 3. 实现编辑区操作栏的功能 3.1. 实现文本加粗.斜体.文本下划线.左对齐.居中对齐.右对齐 3.2. 实现撤销.恢复.插入图片.删除操作 4. 参考 总结 前言 这是我参加掘金启航计划的第三篇文章,这次总结的是实现一个简单的富文本编辑器,相信阅读文章后,观众老爷们,能够实现富文本编辑器,在微信小程序中发布自己的文章,希望观众老爷们多多支持! 1. 实现效果 实现的效果如下图: 实现的功能点如下: 文本加粗.斜体.下划线,对齐方式

  • 微信小程序 两种为对象属性赋值的方式详解

    微信小程序两种为对象属性赋值的方式 对应config.wxml <view> 阶段一<switch id="config1" checked bindchange="switchChange"/> </view> 对应config.js data:{ //定义对象 configs:{} } //方式一 switchChange:function(e){ //为对象的某一属性赋值 configs.config1={ }; conso

  • 微信小程序动态显示项目倒计时效果

    本文实例为大家分享了微信小程序动态显示项目倒计时的具体代码,供大家参考,具体内容如下 1.一般我们说的显示秒杀都是指的单条数据,循环我没做. 效果: 2.wxml代码: <p> <block wx:if="{{total_micro_second<=0}}">剩余时间:已经截止</block> <block wx:if="{{clock!='已经截止'}}">剩余时间:{{clock}}</block>

  • 微信小程序动态显示项目倒计时

    本文实例为大家分享了微信小程序动态显示项目倒计时的具体代码,供大家参考,具体内容如下 1.展示的效果如下 2.wxml代码: <!--倒计时 --> <text wx:if="{{clock!=''}}">仅剩{{clock}}</text> <text wx:if="{{clock==''}}">已经截止</text> 3.js代码: 在拼团项目中获取到活动结束时间的格式为一下格式 因该格式无法正常计算时

  • typescript编写微信小程序创建项目的方法

    创建项目 在微信开发者工具创建项目,在语言中选择 TypeScript 改造项目 编辑 package.json 文件,修改 miniprogram-api-typings 和 typescript 版本 { "name": "miniprogram-ts-quickstart", "version": "1.0.0", "description": "", "scripts&

随机推荐