1.项目目录

2.逻辑层

broadcast.js

  1. // pages/broadcast/broadcast.js
  2. Page({
  3.  
  4. /**
  5. * 页面的初始数据
  6. */
  7. data: {
  8. firstIndex: -1,
  9. //准备数据
  10. //数据结构:以一组一组来进行设定
  11. commodityAttr: [
  12. {
  13. priceId: 1,
  14. price: 35.0,
  15. "stock": 8,
  16. "attrValueList": [
  17. {
  18. "attrKey": "型号",
  19. "attrValue": "2"
  20. },
  21. {
  22. "attrKey": "颜色",
  23. "attrValue": "白色"
  24. },
  25. {
  26. "attrKey": "大小",
  27. "attrValue": "小"
  28. },
  29. {
  30. "attrKey": "尺寸",
  31. "attrValue": "S"
  32. }
  33. ]
  34. },
  35. {
  36. priceId: 2,
  37. price: 35.1,
  38. "stock": 9,
  39. "attrValueList": [
  40. {
  41. "attrKey": "型号",
  42. "attrValue": "1"
  43. },
  44. {
  45. "attrKey": "颜色",
  46. "attrValue": "黑色"
  47. },
  48. {
  49. "attrKey": "大小",
  50. "attrValue": "小"
  51. },
  52. {
  53. "attrKey": "尺寸",
  54. "attrValue": "M"
  55. }
  56. ]
  57. },
  58. {
  59. priceId: 3,
  60. price: 35.2,
  61. "stock": 10,
  62. "attrValueList": [
  63. {
  64. "attrKey": "型号",
  65. "attrValue": "1"
  66. },
  67. {
  68. "attrKey": "颜色",
  69. "attrValue": "绿色"
  70. },
  71. {
  72. "attrKey": "大小",
  73. "attrValue": "大"
  74. },
  75. {
  76. "attrKey": "尺寸",
  77. "attrValue": "L"
  78. }
  79. ]
  80. },
  81. {
  82. priceId: 4,
  83. price: 35.2,
  84. "stock": 10,
  85. "attrValueList": [
  86. {
  87. "attrKey": "型号",
  88. "attrValue": "1"
  89. },
  90. {
  91. "attrKey": "颜色",
  92. "attrValue": "绿色"
  93. },
  94. {
  95. "attrKey": "大小",
  96. "attrValue": "大"
  97. },
  98. {
  99. "attrKey": "尺寸",
  100. "attrValue": "L"
  101. }
  102. ]
  103. }
  104. ],
  105. attrValueList: []
  106. },
  107.  
  108. /**
  109. * 生命周期函数--监听页面加载
  110. */
  111. onLoad: function (options) {
  112.  
  113. },
  114.  
  115. /**
  116. * 生命周期函数--监听页面初次渲染完成
  117. */
  118. onReady: function () {
  119.  
  120. },
  121.  
  122. /**
  123. * 生命周期函数--监听页面显示
  124. */
  125. onShow: function () {
  126. this.setData({
  127. includeGroup: this.data.commodityAttr
  128. });
  129. this.distachAttrValue(this.data.commodityAttr);
  130. // 只有一个属性组合的时候默认选中
  131. // console.log(this.data.attrValueList);
  132. if (this.data.commodityAttr.length == 1) {
  133. for (var i = 0; i < this.data.commodityAttr[0].attrValueList.length; i++) {
  134. this.data.attrValueList[i].selectedValue = this.data.commodityAttr[0].attrValueList[i].attrValue;
  135. }
  136. this.setData({
  137. attrValueList: this.data.attrValueList
  138. });
  139. }
  140. },
  141.  
  142. /* 获取数据 */
  143. distachAttrValue: function (commodityAttr) {
  144. /**
  145. 将后台返回的数据组合成类似
  146. {
  147. attrKey:'型号',
  148. attrValueList:['1','2','3']
  149. }
  150. */
  151. // 把数据对象的数据(视图使用),写到局部内
  152. var attrValueList = this.data.attrValueList;
  153. // 遍历获取的数据
  154. for (var i = 0; i < commodityAttr.length; i++) {
  155. for (var j = 0; j < commodityAttr[i].attrValueList.length; j++) {
  156. var attrIndex = this.getAttrIndex(commodityAttr[i].attrValueList[j].attrKey, attrValueList);
  157. // console.log('属性索引', attrIndex);
  158. // 如果还没有属性索引为-1,此时新增属性并设置属性值数组的第一个值;索引大于等于0,表示已存在的属性名的位置
  159. if (attrIndex >= 0) {
  160. // 如果属性值数组中没有该值,push新值;否则不处理
  161. if (!this.isValueExist(commodityAttr[i].attrValueList[j].attrValue, attrValueList[attrIndex].attrValues)) {
  162. attrValueList[attrIndex].attrValues.push(commodityAttr[i].attrValueList[j].attrValue);
  163. }
  164. } else {
  165. attrValueList.push({
  166. attrKey: commodityAttr[i].attrValueList[j].attrKey,
  167. attrValues: [commodityAttr[i].attrValueList[j].attrValue]
  168. });
  169. }
  170. }
  171. }
  172. // console.log('result', attrValueList)
  173. for (var i = 0; i < attrValueList.length; i++) {
  174. for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
  175. if (attrValueList[i].attrValueStatus) {
  176. attrValueList[i].attrValueStatus[j] = true;
  177. } else {
  178. attrValueList[i].attrValueStatus = [];
  179. attrValueList[i].attrValueStatus[j] = true;
  180. }
  181. }
  182. }
  183. this.setData({
  184. attrValueList: attrValueList
  185. });
  186. },
  187.  
  188. getAttrIndex: function (attrName, attrValueList) {
  189. // 判断数组中的attrKey是否有该属性值
  190. for (var i = 0; i < attrValueList.length; i++) {
  191. if (attrName == attrValueList[i].attrKey) {
  192. break;
  193. }
  194. }
  195. return i < attrValueList.length ? i : -1;
  196. },
  197. isValueExist: function (value, valueArr) {
  198. // 判断是否已有属性值
  199. for (var i = 0; i < valueArr.length; i++) {
  200. if (valueArr[i] == value) {
  201. break;
  202. }
  203. }
  204. return i < valueArr.length;
  205. },
  206.  
  207. /* 选择属性值事件 */
  208. selectAttrValue: function (e) {
  209. /*
  210. 点选属性值,联动判断其他属性值是否可选
  211. {
  212. attrKey:'型号',
  213. attrValueList:['1','2','3'],
  214. selectedValue:'1',
  215. attrValueStatus:[true,true,true]
  216. }
  217. console.log(e.currentTarget.dataset);
  218. */
  219. var attrValueList = this.data.attrValueList;
  220. var index = e.currentTarget.dataset.index;//属性索引
  221. var key = e.currentTarget.dataset.key;
  222. var value = e.currentTarget.dataset.value;
  223. if (e.currentTarget.dataset.status || index == this.data.firstIndex) {
  224. if (e.currentTarget.dataset.selectedvalue == e.currentTarget.dataset.value) {
  225. // 取消选中
  226. this.disSelectValue(attrValueList, index, key, value);
  227. } else {
  228. // 选中
  229. this.selectValue(attrValueList, index, key, value);
  230. }
  231.  
  232. }
  233. },
  234.  
  235. /* 选中 */
  236. selectValue: function (attrValueList, index, key, value, unselectStatus) {
  237. // console.log('firstIndex', this.data.firstIndex);
  238. var includeGroup = [];
  239. if (index == this.data.firstIndex && !unselectStatus) { // 如果是第一个选中的属性值,则该属性所有值可选
  240. var commodityAttr = this.data.commodityAttr;
  241. // 其他选中的属性值全都置空
  242. // console.log('其他选中的属性值全都置空', index, this.data.firstIndex, !unselectStatus);
  243. for (var i = 0; i < attrValueList.length; i++) {
  244. for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
  245. attrValueList[i].selectedValue = '';
  246. }
  247. }
  248. } else {
  249. var commodityAttr = this.data.includeGroup;
  250. }
  251.  
  252. // console.log('选中', commodityAttr, index, key, value);
  253. for (var i = 0; i < commodityAttr.length; i++) {
  254. for (var j = 0; j < commodityAttr[i].attrValueList.length; j++) {
  255. if (commodityAttr[i].attrValueList[j].attrKey == key && commodityAttr[i].attrValueList[j].attrValue == value) {
  256. includeGroup.push(commodityAttr[i]);
  257. }
  258. }
  259. }
  260. attrValueList[index].selectedValue = value;
  261.  
  262. // 判断属性是否可选
  263. for (var i = 0; i < attrValueList.length; i++) {
  264. for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
  265. attrValueList[i].attrValueStatus[j] = false;
  266. }
  267. }
  268. for (var k = 0; k < attrValueList.length; k++) {
  269. for (var i = 0; i < includeGroup.length; i++) {
  270. for (var j = 0; j < includeGroup[i].attrValueList.length; j++) {
  271. if (attrValueList[k].attrKey == includeGroup[i].attrValueList[j].attrKey) {
  272. for (var m = 0; m < attrValueList[k].attrValues.length; m++) {
  273. if (attrValueList[k].attrValues[m] == includeGroup[i].attrValueList[j].attrValue) {
  274. attrValueList[k].attrValueStatus[m] = true;
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }
  281. // console.log('结果', attrValueList);
  282. this.setData({
  283. attrValueList: attrValueList,
  284. includeGroup: includeGroup
  285. });
  286.  
  287. var count = 0;
  288. for (var i = 0; i < attrValueList.length; i++) {
  289. for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
  290. if (attrValueList[i].selectedValue) {
  291. count++;
  292. break;
  293. }
  294. }
  295. }
  296. if (count < 2) {// 第一次选中,同属性的值都可选
  297. this.setData({
  298. firstIndex: index
  299. });
  300. } else {
  301. this.setData({
  302. firstIndex: -1
  303. });
  304. }
  305. },
  306.  
  307. /* 取消选中 */
  308. disSelectValue: function (attrValueList, index, key, value) {
  309. var commodityAttr = this.data.commodityAttr;
  310. attrValueList[index].selectedValue = '';
  311.  
  312. // 判断属性是否可选
  313. for (var i = 0; i < attrValueList.length; i++) {
  314. for (var j = 0; j < attrValueList[i].attrValues.length; j++) {
  315. attrValueList[i].attrValueStatus[j] = true;
  316. }
  317. }
  318. this.setData({
  319. includeGroup: commodityAttr,
  320. attrValueList: attrValueList
  321. });
  322.  
  323. for (var i = 0; i < attrValueList.length; i++) {
  324. if (attrValueList[i].selectedValue) {
  325. this.selectValue(attrValueList, i, attrValueList[i].attrKey, attrValueList[i].selectedValue, true);
  326. }
  327. }
  328. },
  329.  
  330. /* 点击确定 */
  331. submit: function () {
  332. var value = [];
  333. for (var i = 0; i < this.data.attrValueList.length; i++) {
  334. if (!this.data.attrValueList[i].selectedValue) {
  335. break;
  336. }
  337. value.push(this.data.attrValueList[i].selectedValue);
  338. }
  339. if (i < this.data.attrValueList.length) {
  340. wx.showToast({
  341. title: '请完善属性',
  342. icon: 'loading',
  343. duration: 1000
  344. })
  345. } else {
  346. wx.showToast({
  347. title: '选择的属性:' + value.join('-'),
  348. icon: 'sucess',
  349. duration: 1000
  350. })
  351. }
  352. }
  353. })

3.页面布局

broadcast.wxml

  1. <!--pages/broadcast/broadcast.wxml-->
  2. <view class="title">商品属性值联动选择</view>
  3. <!--options-->
  4. <view class="commodity_attr_list">
  5. <!--每组属性-->
  6. <view class="attr_box" wx:for="{{attrValueList}}" wx:for-item="attrValueObj" wx:for-index="attrIndex" wx:key="id">
  7. <!--属性名-->
  8. <view class="attr_name">{{attrValueObj.attrKey}}</view>
  9. <!--属性值-->
  10. <view class="attr_value_box">
  11. <!--每个属性值-->
  12. <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]}}"
  13. 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" wx:key="id">{{value}}</view>
  14. </view>
  15. </view>
  16. </view>
  17. <!--button-->
  18. <view class="weui-btn-area">
  19. <button class="weui-btn" type="primary" bindtap="submit">确定</button>
  20. </view>

4.样式

broadcast.wxss

  1. /* pages/broadcast/broadcast.wxss */
  2. .title {
  3. padding: 10rpx 20rpx;
  4. margin: 10rpx 0;
  5. border-left: 4rpx solid #ccc;
  6. }
  7.  
  8. /*全部属性的主盒子*/
  9. .commodity_attr_list {
  10. background: #fff;
  11. padding: 0 20rpx;
  12. font-size: 26rpx;
  13. overflow: hidden;
  14. width: 100%;
  15. }
  16. /*每组属性的主盒子*/
  17. .attr_box {
  18. width: 100%;
  19. overflow: hidden;
  20. border-bottom: 1rpx solid #ececec;
  21. }
  22. /*属性名*/
  23. .attr_name {
  24. width: 20%;
  25. float: left;
  26. padding: 15rpx 0;
  27. }
  28. /*属性值*/
  29. .attr_value_box {
  30. width: 80%;
  31. float: left;
  32. padding: 15rpx 0;
  33. overflow: hidden;
  34. }
  35. /*每个属性值*/
  36. .attr_value {
  37. float: left;
  38. padding: 0 10rpx;
  39. margin: 0 10rpx;
  40. border: 1rpx solid #ececec;
  41. }
  42. /*每个属性选中的当前样式*/
  43. .attr_value_active {
  44. background: #FFCC00;
  45. border-radius: 10rpx;
  46. color: #fff;
  47. padding: 0 10rpx;
  48. }
  49. /*禁用属性*/
  50. .attr_value_disabled {
  51. color: #ccc;
  52. }
  53.  
  54. /*button*/
  55. .btn-area {
  56. margin: 1.17647059em 15px 0.3em;
  57. }
  58.  
  59. .btn {
  60. margin-top: 15px;
  61. background-color:#FFCC00;
  62. color: #fff;
  63. }
  64. .btn:first-child {
  65. margin-top: 0;
  66. }

5.效果图

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

  1. 微信小程序警告设置 enable-flex 属性以使 flexbox 布局生效的解决办法

    微信小程序警告设置 enable-flex 属性以使 flexbox 布局生效的解决办法 具体情况: scroll-view 滚动,设置 display:flex 不生效并警告设置 enable-fl ...

  2. 微信小程序 input 的 type属性 text、number、idcard、digit 区别

    微信小程序的 input 有个属性叫 type,这个 type 有几个可选值: text:不必解释 number:数字键盘(无小数点) idcard:数字键盘(无小数点.有个 X 键) digit:数 ...

  3. 微信小程序 | app.json配置属性

    app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. widows: 用于设置小程序的状态栏.导航条.标题.窗口背景色. navig ...

  4. 微信小程序 input组件type属性3个值的作用

    input组件是小程序的内容输入框组件,通常是这样来使用的: <input type="text" placeholder="输入点内容吧" /> ...

  5. 微信小程序 wxml中的属性记录

    1. view 标签中的属性 style 中的参数 margin-top:10px;  (向上距离) display : flex;  (display : flex 容器声明) flex-direc ...

  6. 微信小程序 - scroll-view的scroll-into-view属性 - 在页面打开后滚动到指定的项

    需求: 这是一个可横向滚动的导航条,现在要求我,从别的页面reLaunch回到首页这里,刷新页面内容的同时,菜单项要滚动出来 (如果该菜单项不在可视区域),而不是让他被挡住. 代码:<scrol ...

  7. 微信小程序 拼团商品倒计时(拼团列表、拼团商品详情)

    直接上图: 拼团列表.拼团详情-倒计时                                    //单个倒计时,适用用于单个商品的倒计时 js文件: //倒计时 function cou ...

  8. 微信小程序wepy开发,属性绑定的事件参数中可以使用{{}}写实参

    <view wx:for="{{tablist}}" class="item {{activeid === item.id ? 'active':''}}" ...

  9. 微信小程序--flex常用的属性

    Flex布局 display:flex 指定当前盒子为伸缩盒 flex-direction:column 把盒子内容垂直从上往下排列 row 把盒子内容垂直从左往右排列 flex-wrap: wrap ...

随机推荐

  1. C语言中函数参数传递的本质是值传递

    数组名做函数参数进行传递时,实际上是是一份该指针的拷贝. 给形参赋予其他值,并不影响实参的值. 类似于: int *p = a;    //a为数组名 p = b;          //b为数组名 ...

  2. vue获取v-model数据类型boolean改变成string

    问题描述 今天产品问我一线上bug,怎么radio类型改不了 问题分析 看代码,之前的哥们儿是怎么写的 //页面 <div class="ui-form-box"> & ...

  3. 遇到的django问题

    问题1: No migrations to apply 删除了migrations中0001_initial.py文件,重新执行 python manage.py makemigrations pyt ...

  4. JS 手机号中间4位变星号

    一:正则方法 var str1 = '13991367972'var reg = /^(\d{3})\d*(\d{4})$/;var str2 = str1.replace(reg,'$1****$2 ...

  5. 查询mysql所有表数据、字段信息

    根据库名获取所有表的信息 SELECT * FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = 'erp'; 根据库名获取所有表名称和表说明 S ...

  6. 【实验吧】Just Click

    拿到答案需要正确地点击按钮 格式:simCTF{ } 解题链接: http://ctf5.shiyanbar.com/re/rev4.exe 由于最近在学数据库是c#编程,发现是c#,于是用.net ...

  7. playbacktask

    / ** 播放应用程序的头文件. 此文件是头文件,用于定义Playback应用程序的API和数据类型. @file PlaybackTsk.h @ingroup mIAPPPlay @note什么都没 ...

  8. hadoop上传文件报错

    19/06/06 16:09:26 INFO hdfs.DFSClient: Exception in createBlockOutputStream java.io.IOException: Bad ...

  9. luogu3168 [CQOI2015]任务查询系统

    树状数组不用动脑子真爽啊 #include <algorithm> #include <iostream> #include <cstdio> using name ...

  10. sql通配符+sql中查询条件包含下划线等通配符的写法

    一.SQL 通配符 在搜索数据库中的数据时,SQL 通配符可以替代一个或多个字符. SQL 通配符必须与 LIKE 运算符一起使用. 在 SQL 中,可使用以下通配符: 通配符 描述 % 替代一个或多 ...