# lendoo-wx **Repository Path**: luoyt5/lendoo-wx ## Basic Information - **Project Name**: lendoo-wx - **Description**: 灵动电商开源系统之微信小程序端 - **Primary Language**: 微信 - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 321 - **Created**: 2017-01-04 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ##LXStepper组件,用于购物车商品数量的加减。 >翻看了个文档,微信没有提供现成的组件,于是写了这个小widget。 ![git](https://static.oschina.net/uploads/img/201610/27155649_MeBK.gif "效果展示") 总体思路: 最左边框,最右边框由最后外层的容器的border-left与border-right设定;中间2段由input来设定;左右按钮不设边框,圆角效果由最外面容器来设定,这样刚好实现了一个耳熟能详的stepper样式。 1. 布局: 1.1 准备一个容器view,设置它的宽为width: 70px;height: 21px;边框颜色为#ccc灰色;圆角3px; 1.2 内置3个组件,分别是左text,中input,右text,之所以不用button是因为系统自带的button带了样式,为了遵守设计规范,不去重写button的样式。其中input的默认高度是21px。宽度分别为19px,30px,19px,之所以是19px,是因为容器带了左右边距,共占据了2px。 1.3 3个组件都是文字居中,text-align: center实现;垂直居中使用line-height: 21px来实现 1.4 3个组件都是向左浮动,由于我们计算好3个组件的宽度绝对值,于是不必设定加号按钮的浮动float: right ![图1](https://static.oschina.net/uploads/img/201610/10213317_FAph.png "初始") 布局文件代码 ``` - + ``` 样式表代码 ``` /*stepper容器*/ .stepper { border: 1px solid #ccc; border-radius: 3px; width: 70px; height: 21px; margin:0 auto; } /*加号与减号*/ .stepper text { width: 19px; height: 28px; line-height: 21px; text-align: center; float: left; } /*数值*/ .stepper input { float: left; margin: 0 auto; width: 30px; text-align: center; font-size: 12px; border-left: 1px solid #ccc; border-right: 1px solid #ccc; } ``` 2. 绑定事件 2.1 准备两个按钮样式分别对应普通与禁用状态 ``` /*普通样式*/ .stepper .normal{ color: black; } /*禁用样式*/ .stepper .disabled{ color: #ccc; } ``` 还要准备一个data的值对象,用于监测数值与状态的改变: ``` data: { num: 1, minusStatus: 'disabled' } ``` 2.2 加号与减号事件 2.2.1 绑定text事件bindtap,分别是bindMinus,bindPlus。按如下处理:取出data中的num值后作自增与自减,对于自减操作要先判断是否大于1才做自减操作,也就是说已经是1的时候,就不要自减了 2.2.2 当num已经为1的时候,我们将减号按钮设置为disabled样式,一旦大于1,又变回normal状态,加减事件均要如此处理,不然到了临界值1的时候,回不到normal状态 js代码: ``` bindMinus: function() { var num = this.data.num; // 如果只有1件了,就不允许再减了 if (num > 1) { num --; } // 只有大于一件的时候,才能normal状态,否则disable状态 var minusStatus = num <= 1 ? 'disabled' : 'normal'; // 将数值与状态写回 this.setData({ num: num, minusStatus: minusStatus }); }, ``` 效果如图,注意减号是灰色的#ccc ![图2](https://static.oschina.net/uploads/img/201610/10213354_fdYl.png "加入了禁用状态") 2.3 文本框输入事件 2.3.1 在wxml文件中的input输入框监听值变更事件bindchange="bindManual"。注:bindchange是失去焦点才会调用一次的,而bininput是每当有值有改变会有调用一次,敲打123,则会产生值1,12,123三次,比较适合于输入验证。 2.3.2 实现bindManual ``` bindManual: function(e) { var num = e.detail.value; // 将数值与状态写回 this.setData({ num: num }); } ``` 这个步骤看似多余,实则为了num个数同步,以作为提交到网络数据时是真正的data.num,而不是input手工改写的数值 [2016-10-11] fix iPhone6 height bug ```.stepper input {height: 26px}``` ##LXCheckboxGroup复选框 >微信小程序官方提供的checkbox有点丑,于是就写了这个。 ![图2-0](https://static.oschina.net/uploads/img/201610/11160900_Cd0j.gif "复选框效果图") 思路: 1.checkboxGroup里包着一个checkbox view组件 2.每个checkbox里都包含一个icon与text 3.icon与text点击都会选中,类似于label for的用法,icon样式会切换状态。normal与highlight状态,对应的值赋予icon的type属性。 4.每个checkbox的view都有一个value属性与text属性,分别对应实现值与字面显示,只转递前者作为数据交互。view设定2个属性,data-value与data-text。 5.每次点击都会将checkbox的value值存在到checkedValues数组中 步骤: 1. 设置布局,使用文字与图标垂直居中,左间距4px,每个独占一行。 布局文件 ``` {{item.text}} ``` 样式表 ``` /*整个复选框组容器*/ .lxCheckboxGroup { width: 80px; height: 26px; margin:20px auto; } /*单个复选框容器*/ .lxCheckboxGroup view { /*上下间距4px*/ margin: 4px auto; } /*复选框图标*/ .lxCheckboxGroup icon { /*text用block描述,所以要左浮动*/ float: left; } /*文字标签样式*/ .lxCheckboxGroup text{ font-size: 14px; /*20px是左按钮的大小,4px是真实的左间距*/ margin-left: 24px; /*高亮与icon相等,实现垂直居中*/ height: 20px; /*文本垂直居中*/ line-height: 20px; /*块布局,否则文本高度无效*/ display: block; } ``` js代码 ``` Page({ data: { items: [ {value: 'USA', text: '美国', type: 'circle'}, {value: 'CHN', text: '中国', type: 'success_circle'}, {value: 'BRA', text: '巴西', type: 'circle'}, {value: 'JPN', text: '日本', type: 'circle'}, {value: 'ENG', text: '英国', type: 'circle'}, {value: 'TUR', text: '法国', type: 'circle'}, ] }, bindCheckbox: function(e) { //绑定点击事件,将checkbox样式改变为选中与非选中 console.log('s' + e.currentTarget.dataset.value); } }) ``` 如图 ![图2-1](https://static.oschina.net/uploads/img/201610/11160611_0TSe.png "布局图") 2. 响应点击事件 2.1 利用e.currentTarget.dataset.index传checkbox的index值,作点选与非点选操作,并将已选的values值单独存到数组checkedValues中,供返回提交等操作。 ``` bindCheckbox: function(e) { /*绑定点击事件,将checkbox样式改变为选中与非选中*/ //拿到下标值,以在items作遍历指示用 var index = parseInt(e.currentTarget.dataset.index); //原始的icon状态 var type = this.data.items[index].type; var items = this.data.items; if (type == 'circle') { //未选中时 items[index].type = 'success_circle'; } else { items[index].type = 'circle'; } // 写回经点击修改后的数组 this.setData({ items: items }); // 遍历拿到已经勾选的值 var checkedValues = []; for (var i = 0; i < items.length; i++) { if (items[i].type == 'success_circle') { checkedValues.push(items[i].value); } } // 写回data,供提交到网络 this.setData({ checkedValues: checkedValues }); } ``` 3. text也需要绑定bindCheckBox事件,产生label for的效果,但还可以更简单的处理,就是把事件绑在容器view上,这样点击更直观。 如下面代码: ``` {{item.text}} ``` ##购物车 [2016-10-14] 设计思路: 一、从网络上传入以下Json数据格式的数组 1.购物车id:cid 2.标题title 3.数量num 4.图片地址 5.价格price 6.小计 7.是否选中selected 二、点击复选框toggle操作 如已经选中的,经点击变成未选中,反之而反之 点击依据index作为标识,而不用cid,方便遍历 三、全选操作 首次点击即为全部选中,再次点击为全不选,全选按钮本身也跟随toggle变换 四、点击结算按钮,将已选中的cid数组取出,以供通过网络提交到服务端,这里给个toast作为结果演示。 五、利用stepper作加减运算,同样依据index作为标识,点完写回num值。 六、布局,全选与结算按钮底部对齐,购物车商城自适应高度,类似于Android的weight。 步骤: 1. 初始数据渲染 1.1 布局与样式表 上方是一个商品列表,下方是一个全选按钮与立即结算按钮 商品列表左部为商品缩略图,右上为商品标题,右下为商品价格与数量,其中商品数量使用WXStepper来实现加减操作 js:初始化一个数据源,这往往是从网络获取的,相关接口可参见:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html ``` Page({ data:{ carts: [ {cid:1008,title:'Zippo打火机',image:'https://img12.360buyimg.com/n7/jfs/t2584/348/1423193442/572601/ae464607/573d5eb3N45589898.jpg',num:'1',price:'198.0',sum:'198.0',selected:true}, {cid:1012,title:'iPhone7 Plus',image:'https://img13.360buyimg.com/n7/jfs/t3235/100/1618018440/139400/44fd706e/57d11c33N5cd57490.jpg',num:'1',price:'7188.0',sum:'7188.0',selected:true}, {cid:1031,title:'得力订书机',image:'https://img10.360buyimg.com/n7/jfs/t2005/172/380624319/93846/b51b5345/5604bc5eN956aa615.jpg',num:'3',price:'15.0',sum:'45.0',selected:false}, {cid:1054,title:'康师傅妙芙蛋糕',image:'https://img14.360buyimg.com/n7/jfs/t2614/323/914471624/300618/d60b89b6/572af106Nea021684.jpg',num:'2',price:'15.2',sum:'30.4',selected:false}, {cid:1063,title:'英雄钢笔',image:'https://img10.360buyimg.com/n7/jfs/t1636/60/1264801432/53355/bb6a3fd1/55c180ddNbe50ad4a.jpg',num:'1',price:'122.0',sum:'122.0',selected:true}, ] } }) ``` 布局文件 ``` {{item.title}} {{item.sum}} WXStepper ``` 样式表 ``` /*外部容器*/ .container { display: flex; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box; } /*整体列表*/ .carts-list { display: flex; flex-direction: column; padding: 20rpx 40rpx; } /*每行单元格*/ .carts-item { display: flex; flex-direction: row; height:150rpx; /*width属性解决标题文字太短而缩略图偏移*/ width:100%; border-bottom: 1px solid #eee; padding: 30rpx 0; } /*左部图片*/ .carts-image { width:150rpx; height:150rpx; } /*右部描述*/ .carts-text { width: 100%; display: flex; flex-direction: column; justify-content: space-between; } /*右上部分标题*/ .carts-title { margin: 10rpx; font-size: 30rpx; } /*右下部分价格与数量*/ .carts-subtitle { font-size: 25rpx; color:darkgray; padding: 0 20rpx; display: flex; flex-direction: row; justify-content:space-between; } /*价格*/ .carts-price { color: #f60; } ``` ![图3-1](https://static.oschina.net/uploads/img/201610/14153754_gc9Z.png "基本布局") 1.2 集成WXStepper 1.2.1 复制组件内容 [2016-10-16] 将stepper.wxss的内容复制到cart.wxss中 将stepper.wxml的内容复制到cart.wxml中 与之前的单一组件不同的是:这里要定义数组minusStatuses来与每一个加减按钮相应。当然,合并入carts也是没问题的。 ``` minusStatuses: ['disabled', 'disabled', 'normal', 'normal', 'disabled'] ``` 原来的静态字符WXStepper换成以下的代码 ``` - + ``` js代码bindMinus、bindPlus分别改造为如下: ``` bindMinus: function(e) { var index = parseInt(e.currentTarget.dataset.index); var num = this.data.carts[index].num; // 如果只有1件了,就不允许再减了 if (num > 1) { num --; } // 只有大于一件的时候,才能normal状态,否则disable状态 var minusStatus = num <= 1 ? 'disabled' : 'normal'; // 购物车数据 var carts = this.data.carts; carts[index].num = num; // 按钮可用状态 var minusStatuses = this.data.minusStatuses; minusStatuses[index] = minusStatus; // 将数值与状态写回 this.setData({ carts: carts, minusStatuses: minusStatuses }); }, bindPlus: function(e) { var index = parseInt(e.currentTarget.dataset.index); var num = this.data.carts[index].num; // 自增 num ++; // 只有大于一件的时候,才能normal状态,否则disable状态 var minusStatus = num <= 1 ? 'disabled' : 'normal'; // 购物车数据 var carts = this.data.carts; carts[index].num = num; // 按钮可用状态 var minusStatuses = this.data.minusStatuses; minusStatuses[index] = minusStatus; // 将数值与状态写回 this.setData({ carts: carts, minusStatuses: minusStatuses }); }, ``` 效果如图: ![图4-1](https://static.oschina.net/uploads/img/201610/16214421_U41q.png "带加减按钮的购物车") [2016-10-17] 修正手工改动数量保存到数组 1.3 集成LXCheckboxGroup 复制布局文件代码到wxml,这里需要判断一下已选状态,一般购物车勾选状态是记录在网络的。 index值用于传值js,遍历之用。 ``` ``` 复选框居中 ``` /*复选框样式*/ .carts-list icon { margin-top: 60rpx; margin-right: 20rpx; } ``` 绑定点击复选框事件,对选择状态做反选操作。 ``` bindCheckbox: function(e) { /*绑定点击事件,将checkbox样式改变为选中与非选中*/ //拿到下标值,以在carts作遍历指示用 var index = parseInt(e.currentTarget.dataset.index); //原始的icon状态 var selected = this.data.carts[index].selected; var carts = this.data.carts; // 对勾选状态取反 carts[index].selected = !selected; // 写回经点击修改后的数组 this.setData({ carts: carts }); } ``` 效果图: ![图5-1](https://static.oschina.net/uploads/img/201610/17102724_I5vQ.png "复选框") 1.4 加入全选与立即结算按钮 1.4.1 修改布局文件,实现上述按钮底部对齐,使用flex与固定高度来完成。 减少为3行,看是否还在最底;此外,还要保证悬浮在底部,不被列表项的滚动而滚动。 ``` 全选 立即结算 ``` 之前用来实现,发现无论如何都不能实现全选部件与结算按钮分散对齐,不响应如下样式 ``` display: flex; flex-direction: row; justify-content: space-between; ``` 样式表 ``` /*底部按钮*/ .carts-footer { width: 100%; height: 80rpx; display: flex; flex-direction: row; justify-content: space-between; } /*复选框*/ .carts-footer icon { margin-left: 20rpx; } /*全选字样*/ .carts-footer text { font-size: 30rpx; margin-left: 8rpx; line-height: 10rpx; } /*立即结算按钮*/ .carts-footer .button { line-height: 80rpx; text-align: center; width:220rpx; height: 80rpx; background-color: #f60; color: white; font-size: 36rpx; border-radius: 0; border: 0; } ``` 1.4.2 全选与全不选事件 实现bindSelectAll事件,改变全选状态 首先定义一个data值,以记录全选状态 ``` selectedAllStatus: false ``` 事件实现: ``` bindSelectAll: function() { // 环境中目前已选状态 var selectedAllStatus = this.data.selectedAllStatus; // 取反操作 selectedAllStatus = !selectedAllStatus; // 购物车数据,关键是处理selected值 var carts = this.data.carts; // 遍历 for (var i = 0; i < carts.length; i++) { carts[i].selected = selectedAllStatus; } this.setData({ selectedAllStatus: selectedAllStatus, carts: carts }); } ``` ![图6-1](https://static.oschina.net/uploads/img/201610/17154657_V1CQ.png "结算按钮") 1.4.3 立即结算显示目前所选的cid,以供提交到网络,商品数量应该是包括在cid中的,后端设计应该只关注cid与uid 布局文件也埋一下toast,js只要改变toast的显示与否即可。 ``` ``` 为立即结算绑定事件bindCheckout,弹出cid弹窗 ``` bindCheckout: function() { // 初始化toastStr字符串 var toastStr = 'cid:'; // 遍历取出已勾选的cid for (var i = 0; i < this.data.carts.length; i++) { if (this.data.carts[i].selected) { toastStr += this.data.carts[i].cid; toastStr += ' '; } } //存回data this.setData({ toastHidden: false, toastStr: toastStr }); }, bindToastChange: function() { this.setData({ toastHidden: true }); } ``` 1.5 底部悬浮固定 1.5.1 商品列表 .carts-list 加入 margin-bottom: 80rpx; 以及修改上边距为零,使得底部部件与分隔不重复出现,padding: 0 40rpx; 1.5.2 底部按钮 .carts-footer 加入 background: white; 1.5.3 .carts-footer 加入 ``` position: fixed; bottom: 0; border-top: 1px solid #eee; ``` ![图6-1](https://static.oschina.net/uploads/img/201610/17163555_PUmd.png "底部悬浮") 1.6 汇总 1.6.1 首先定义一个数据源,并在布局文件中埋坑 total: '' {{total}} 1.6.2 通用汇总函数 ``` sum: function() { var carts = this.data.carts; // 计算总金额 var total = 0; for (var i = 0; i < carts.length; i++) { if (carts[i].selected) { total += carts[i].num * carts[i].price; } } // 写回经点击修改后的数组 this.setData({ carts: carts, total: '¥' + total }); } ``` 然后分别在bindMinus bindPlus bindCheckbox bindSelectAll onLoad中调用this.sum() 如图: ![图6-3](https://static.oschina.net/uploads/img/201610/17195800_Xq64.png "价格汇总") [2016-10-30] #基于LeanCloud实现访问网络与数据存储 ![](https://static.oschina.net/uploads/img/201610/30171911_bYLF.gif "效果图") ##目标 使用LeanCloud JS_SDK读取电商系统的商品分类 ##准备 在https://www.leancloud.cn上注册帐号,创建仓库,建Category表,建title字段 ##无限级分类建表结构 建立字段parent,类型为Pointer,指向Category对象 ![输入图片说明](https://static.oschina.net/uploads/img/201610/30171856_qPiR.png "数据") ##下载JS_SDK https://unpkg.com/leancloud-storage@2.0.0-beta.2/dist/av-weapp.js 文档出处:https://leancloud.cn/docs/weapp.html ##安装 将上面的js文件保存此util目录 ##使用 在category.js中引入 const AV = require('../../utils/av-weapp.js') 连接数据仓库,取查询所有分类 ``` Page({ onLoad: function(){ AV.init({ appId: "SgHcsYqoLaFTG0XDMD3Gtm0I-gzGzoHsz", appKey: "xdv2nwjUK5waNglFoFXkQcxP", }); var query = new AV.Query('Category'); query.find().then(function (categories) { for (var i = 0; i < categories.length; i++) { var category = categories[i]; console.log(category.attributes.title); } }).catch(function(error) { alert(JSON.stringify(error)); }); } }) ``` 这时控件台可以看到输出category所有分类 潮流女装 连衣裙 针织开衫 羽绒服 时尚T恤 家用电器 电视 空调 ##条件查询获得顶级分类 ``` query.equalTo('parent',null); ``` 这时控件台可以看到输出category顶级分类 潮流女装 家用电器 ##Pointer方式查询二级分类 ``` // 查询父级分类下的所有子类 var parent = AV.Object.createWithoutData('Category', '581415bf2e958a005492150b'); query.equalTo('parent',parent); ``` 这时控件台可以看到输出category潮流女装分类下的所有子类 ``` 连衣裙 针织开衫 羽绒服 时尚T恤 ``` ##配合布局与js文件,实现分类页面 wxml: ``` {{item.title}}
{{item.title}}
``` wxss ``` /*页面背景*/ page { background-color: #f3f5f7; } /*容器总体布局为左右两列*/ .container { display: flex; flex-direction: row; justify-content: space-between; } /*侧边栏顶级分类给予固定宽度*/ .sidebar { width: 120px; border-top: 1px solid #e5e5e5; height: 568px; } /*text块状布局独占一行*/ .sidebar text { display: block; border: 1px solid #e5e5e5; border-top: 0; height: 40px; line-height: 40px; text-align: center; color: #232626; font-size: 14px; background-color: #fff; } /*hight light*/ .sidebar text.highlight { background-color: #f3f5f7; color: #f23131; border-right: 0; } /*网格布局子类九宫格分布*/ .gridview { width: 100%; background-color: #fff; margin-left: 5px; } /*向左流动*/ .gridview dl { float: left; margin: 5px; } /*图片*/ .gridview dt image { width: 60px; height: 60px; } /*文字*/ .gridview dd text { color: #6c6c6c; font-size: 12px; text-align: center; display: block; line-height: 20px; } ``` js: ``` const AV = require('../../utils/av-weapp.js') Page({ data: { topCategories: [], subCategories: [], highlight:['highlight','',''] }, onLoad: function(){ this.getCategory(null); // hard code to read default category,maybe this is a recommend category later. this.getCategory(AV.Object.createWithoutData('Category', '581415bf2e958a005492150b')); }, tapTopCategory: function(e){ // 拿到objectId,作为访问子类的参数 var objectId = e.currentTarget.dataset.objectId; // 查询父级分类下的所有子类 var parent = AV.Object.createWithoutData('Category', objectId); this.getCategory(parent); // 设定高亮状态 var index = parseInt(e.currentTarget.dataset.index); this.setHighlight(index); }, getCategory: function(parent){ var that = this; var query = new AV.Query('Category'); // 查询顶级分类,设定查询条件parent为null query.equalTo('parent',parent); query.find().then(function (categories) { if (parent){ that.setData({ subCategories: categories }); }else{ that.setData({ topCategories: categories }); } }).catch(function(error) { }); }, setHighlight: function(index){ var highlight = []; for (var i = 0; i < this.data.topCategories; i++) { highlight[i] = ''; } console.log(index); highlight[index] = 'highlight'; this.setData({ highlight: highlight }); } }) ``` # 12-27 更新了收货地址三级城市选择器,弃用原picker的做法 通过本文可以读到: 1. 省级上下滚动展示scroll-view基本用法 2. 省市级之间左右滑动展示swiper基本用法 3. data-index传值方法,wx:for循环语句、wf:if条件判断语句写法 先看下最终效果: ![最终效果](https://static.oschina.net/uploads/img/201612/27114248_fZWd.gif "在这里输入图片标题") ## 一、scroll-view ### 1. scroll-view组件布局 ``` {{item}} ``` 解释:scroll滚动方向项默认值是false,于是**将scroll-y设为true**。 效果如图: ![输入图片说明](https://static.oschina.net/uploads/img/201612/27095236_g91i.gif "在这里输入图片标题") ### 2.相应的样式表这么写: ``` /*地址列表ListView容器*/ .viewpager-listview { padding-top: 5px; height: 220px; } /*每行地址item项*/ .viewpager-listview view{ line-height: 30px; padding: 0 10px; } ``` 说明:height: 220px高度是必选项,**否则上下滚动无效**。 如图: ![输入图片说明](https://static.oschina.net/uploads/img/201612/27095435_ThLc.gif "在这里输入图片标题") 文档传送门:[https://mp.weixin.qq.com/debug/wxadoc/dev/component/scroll-view.html](https://mp.weixin.qq.com/debug/wxadoc/dev/component/scroll-view.html) ## 二、swiper ``` {{item}} .swiper-area { height:220px; } ``` 说明:上面写的scroll-view包在标签里就可以了,样式表里定义height即可,indicator-dots="true" autoplay="true" interval="5000" duration="1000"对于做首页轮播广告大图有必要,**而这里不需要**。 文档传送门:[https://mp.weixin.qq.com/debug/wxadoc/dev/component/swiper.html](https://mp.weixin.qq.com/debug/wxadoc/dev/component/swiper.html) ## 三、点击省级触发swiper滚动事件 方法是设置swiper的current属性值 绑定事件:{{item}} 实现事件: ``` provinceTapped: function() { this.setData({ current: 1 }); } ``` 如图: ![输入图片说明](https://static.oschina.net/uploads/img/201612/27102056_i3hO.gif "在这里输入图片标题") ## 四、实现市级数据加载 为了记录点击的是哪一个省,设定一个data-index="{{index}}"来标识 ``` {{item}} ``` 在相应的js代码中记录下来该index,并触发省级改变事件this.provinceIndexChanged(index) ``` provinceTapped: function(e) { // 标识当前点击省份,记录省份名称与主键id都依赖它 var index = e.currentTarget.dataset.index; this.setData({ current: 1, provinceIndex: index }); this.provinceIndexChanged(index); }, ``` provinceIndexChanged实现如下: ``` provinceIndexChanged: function(index) { //provinceObjects是一个leanCloud对象,通过遍历得到纯字符串数组 // getArea方法是访问网络请求数据,网络访问正常则一个回调function(area){} this.getArea(this.data.provinceObjects[index].get('aid'), function (area) { var array = []; for (var i = 0; i < area.length; i++) { array[i] = area[i].get('name'); } // city就是wxml中渲染要用到的城市数据,cityObjects是LeanCloud对象,用于县级标识取值 that.setData({ city: array, cityObjects: area }); }); }, ``` 最后就是将city数据渲染到wxml了 ``` {{item}} ``` 效果如下: ![输入图片说明](https://static.oschina.net/uploads/img/201612/27105702_Wu9i.gif "在这里输入图片标题") ## 五、高亮列表当前选中省份 目前点击选中的省份没有高亮,不是很醒目,于是加上一个area-selected样式为红色 原来的省份代码修改如下: ``` {{item}} {{item}} ``` 如果数组index下标等于当于provinceIndex,就设定一个area-selected样式。 效果如下: ![效果](https://static.oschina.net/uploads/img/201612/27113234_VEnt.gif "效果") ## 六、美化标题,由请选择显示为当前省份名称 ``` {{provinceName}} this.setData({ current: 1, provinceIndex: index, provinceName: this.data.province[index] }); ``` ![最终效果](https://static.oschina.net/uploads/img/201612/27114248_fZWd.gif "在这里输入图片标题") 对小程序开发有趣的朋友关注公众号: huangxiujie85,QQ群: 581513218,微信: small_application,陆续还将推出更多作品。 ![公众号](https://static.oschina.net/uploads/img/201610/07111145_qD6d.jpg "二维码")