小程序公共组件之地址选择五级联动
1 <!--components/area-select.wxmlby:张涛20180308--> 2 <view class="area-select-bg" wx:if="{{isShow}}"> 3 <view class="area-select-box"> 4 <view class="area-select-title"> 5 <view catchtap='_cancelEvent' class="select-off">取消</view> 6 地址选择 7 <view catchtap='_confirmEvent' class="select-on">确认</view> 8 </view> 9 <view class="area-select-btn"> 10 <view class="area-select-btn-item" wx:if="{{selectNum>0}}" id="1" bindtap="tabBtn">{{provinceName}}</view> 11 <view class="area-select-btn-item" wx:if="{{selectNum>1}}" id="2" bindtap="tabBtn">{{cityName}}</view> 12 <view class="area-select-btn-item" wx:if="{{selectNum>2}}" id="3" bindtap="tabBtn">{{areaName}}</view> 13 <view class="area-select-btn-item" wx:if="{{selectNum>3}}" id="4" bindtap="tabBtn">{{addressName}}</view> 14 <view class="area-select-btn-item" wx:if="{{selectNum>=4}}" id="5" bindtap="tabBtn">{{communityName}}</view> 15 <view class="area-select-btn-active area-select-btn-item" wx:if="{{isHaveSubset}}">请选择</view> 16 </view> 17 <view class="area-select-show"> 18 <scroll-view scroll-y style="height:660rpx;"> 19 <block wx:for="{{list}}" wx:key=""> 20 <view class="area-select-show-item" data-item="{{item}}" bindtap="selectBtn"> 21 <view class="area-select-show-item-name" style="color:{{item.checked?'#ea8842':''}}">{{item.name}}</view> 22 <image class="area-select-show-item-checked" wx:if="{{item.checked}}" src="/img/select-on.png"></image> 23 </view> 24 </block> 25 </scroll-view> 26 </view> 27 </view> 28 </view>
1 // components/area-select.js by:张涛20180308 2 const util = require('../../utils/request.js'); 3 Component({ 4 /** 5 * 组件的属性列表 6 */ 7 properties: { 8 9 }, 10 11 /** 12 * 组件的初始数据 13 */ 14 data: { 15 isShow:false, 16 // 公用列表数据 17 list:[], 18 // 获取的列表数组 19 area:{ 20 province:[], 21 city:[], 22 area:[], 23 address:[], 24 community:[] 25 }, 26 // 地址code 27 provinceCode:'', 28 cityCode:'', 29 areaCode:'', 30 addressCode:'', 31 // 选择按钮 32 selectNum:0, 33 // 地址名称 34 provinceName:'', 35 cityName:'', 36 areaName:'', 37 addressName:'', 38 communityName:'', 39 // 判断是否还有下一级 40 isHaveSubset:true, 41 // 外部使用的数据包,如需使用地址数据请,在外部定义后直接调用this.data.addressObj即可 42 addressObj:{ 43 province:'', 44 city:'', 45 area:'', 46 address:'', 47 community:'' 48 }, 49 // 请求函数通道 50 getBol:false 51 }, 52 /* 53 *组件生命周期函数,在组件实例进入页面节点树时执行 54 */ 55 attached:function(){ 56 this.getProvince(); 57 }, 58 /** 59 * 组件的方法列表 60 */ 61 methods: { 62 //隐藏弹框 63 hideDialog(){ 64 this.setData({ 65 isShow: !this.data.isShow 66 }) 67 }, 68 //展示弹框 69 showDialog(){ 70 this.setData({ 71 isShow: !this.data.isShow 72 }) 73 }, 74 /* 75 * 内部私有方法建议以下划线开头 76 * triggerEvent 用于触发事件 77 */ 78 _cancelEvent(){ 79 //触发取消回调 80 this.triggerEvent("cancelEvent"); 81 }, 82 _confirmEvent(){ 83 // 判断地址是否选择完毕 84 if (this.data.isHaveSubset) { 85 return false; 86 } 87 //触发成功回调 88 this.triggerEvent("confirmEvent"); 89 }, 90 /* 91 * 公有方法 92 */ 93 // 地址三级请求函数 94 // 省 95 getProvince(){ 96 var _this=this; 97 util.POST('/mobile/common/getArea','',{'parentCode':this.data.provinceCode},function(res){ 98 // 为所有的省添加checked 99 res.data.result.forEach(function(item){ 100 item.checked=false; 101 }) 102 _this.data.area.province=res.data.result; 103 _this.setData({ 104 area:_this.data.area, 105 list:res.data.result 106 }) 107 }) 108 }, 109 // 市 110 getCity(){ 111 var _this=this; 112 util.POST('/mobile/common/getArea','',{'parentCode':this.data.provinceCode},function(res){ 113 // 为所有的省添加checked 114 res.data.result.forEach(function(item){ 115 item.checked=false; 116 }) 117 _this.data.area.city=res.data.result; 118 _this.setData({ 119 area:_this.data.area, 120 list:res.data.result 121 }) 122 }) 123 }, 124 // 区 125 getArea(){ 126 var _this=this; 127 util.POST('/mobile/common/getArea','',{'parentCode':this.data.cityCode},function(res){ 128 // 为所有的省添加checked 129 res.data.result.forEach(function(item){ 130 item.checked=false; 131 }) 132 _this.data.area.area=res.data.result; 133 _this.setData({ 134 area:_this.data.area, 135 list:res.data.result 136 }) 137 }) 138 }, 139 // 街道 140 getAddress(){ 141 var _this=this; 142 util.POST('/mobile/common/getArea','',{'parentCode':this.data.areaCode},function(res){ 143 // 为所有的省添加checked 144 res.data.result.forEach(function(item){ 145 item.checked=false; 146 }) 147 _this.data.area.address=res.data.result; 148 _this.setData({ 149 area:_this.data.area, 150 list:res.data.result 151 }) 152 }) 153 }, 154 // 小区 155 getCommunity(){ 156 var _this=this; 157 util.POST('/mobile/common/getArea','',{'parentCode':this.data.addressCode},function(res){ 158 // 为所有的省添加checked 159 res.data.result.forEach(function(item){ 160 item.checked=false; 161 }) 162 _this.data.area.community=res.data.result; 163 _this.setData({ 164 area:_this.data.area, 165 list:res.data.result 166 }) 167 }) 168 }, 169 // 点击tab进行切换 170 tabBtn(event){ 171 // 判断点击的级别 172 if (event.currentTarget.id==1) { 173 // 更新列表 174 this.data.list=this.data.area.province; 175 // 更新点击框 176 this.data.selectNum=0; 177 }else if (event.currentTarget.id==2) { 178 this.data.list=this.data.area.city; 179 this.data.selectNum=1; 180 }else if (event.currentTarget.id==3) { 181 this.data.list=this.data.area.area; 182 this.data.selectNum=2; 183 }else if (event.currentTarget.id==4) { 184 this.data.list=this.data.area.address; 185 this.data.selectNum=3; 186 }else if (event.currentTarget.id==5) { 187 this.data.list=this.data.area.community; 188 this.data.selectNum=4; 189 } 190 this.setData({ 191 list:this.data.list, 192 selectNum:this.data.selectNum, 193 isHaveSubset:this.data.list[0]?true:false 194 }) 195 }, 196 // 点击地址进行选择处理 197 selectBtn(event){ 198 // 清空列表 199 this.setData({ 200 list:[] 201 }) 202 // 判断当前的点击区域selectNum值 0:省。1:市。2:区。3:街道。 203 if (this.data.selectNum==0) { 204 // 保存信息 205 this.data.area.province.forEach(function(item){ 206 if (item.code==event.currentTarget.dataset.item.code) { 207 item.checked=true; 208 }else{ 209 item.checked=false; 210 } 211 }) 212 this.data.selectNum=1; 213 this.setData({ 214 provinceCode:event.currentTarget.dataset.item.code, 215 area:this.data.area, 216 selectNum:this.data.selectNum, 217 provinceName:event.currentTarget.dataset.item.name, 218 isHaveSubset:event.currentTarget.dataset.item.isHaveSubset?true:false 219 }) 220 this.getCity(); 221 } 222 // 市 223 else if (this.data.selectNum==1) { 224 // 保存信息 225 this.data.area.city.forEach(function(item){ 226 if (item.code==event.currentTarget.dataset.item.code) { 227 item.checked=true; 228 }else{ 229 item.checked=false; 230 } 231 }) 232 this.data.selectNum=2; 233 this.setData({ 234 cityCode:event.currentTarget.dataset.item.code, 235 area:this.data.area, 236 selectNum:this.data.selectNum, 237 cityName:event.currentTarget.dataset.item.name, 238 isHaveSubset:event.currentTarget.dataset.item.isHaveSubset?true:false 239 }) 240 this.getArea(); 241 }else if(this.data.selectNum==2){ 242 // 保存信息 243 this.data.area.area.forEach(function(item){ 244 if (item.code==event.currentTarget.dataset.item.code) { 245 item.checked=true; 246 }else{ 247 item.checked=false; 248 } 249 }) 250 this.data.selectNum=3; 251 this.setData({ 252 areaCode:event.currentTarget.dataset.item.code, 253 area:this.data.area, 254 selectNum:this.data.selectNum, 255 areaName:event.currentTarget.dataset.item.name, 256 isHaveSubset:event.currentTarget.dataset.item.isHaveSubset?true:false 257 }) 258 // 判断是否还有下一级// 由于数据源不对等,有三级数据源,所以需要做数据重置处理以免造成返回数据叠加问题 259 if (!this.data.isHaveSubset) { 260 this.setData({ 261 addressCode:'', 262 addressName:'', 263 communityName:'', 264 communityCode:'' 265 }) 266 } 267 this.getAddress(); 268 269 }else if (this.data.selectNum==3) { 270 // 保存信息 271 this.data.area.address.forEach(function(item){ 272 if (item.code==event.currentTarget.dataset.item.code) { 273 item.checked=true; 274 }else{ 275 item.checked=false; 276 } 277 }) 278 this.data.selectNum=4; 279 this.setData({ 280 addressCode:event.currentTarget.dataset.item.code, 281 area:this.data.area, 282 selectNum:this.data.selectNum, 283 addressName:event.currentTarget.dataset.item.name, 284 isHaveSubset:event.currentTarget.dataset.item.isHaveSubset?true:false 285 }) 286 // 由于数据源不对等,有三级数据源,所以需要做数据重置处理以免造成返回数据叠加问题 287 if (!this.data.isHaveSubset) { 288 this.setData({ 289 communityName:'', 290 communityCode:'' 291 }) 292 } 293 this.getCommunity(); 294 }else if(this.data.selectNum==4){ 295 // 保存信息 296 this.data.area.community.forEach(function(item){ 297 if (item.code==event.currentTarget.dataset.item.code) { 298 item.checked=true; 299 }else{ 300 item.checked=false; 301 } 302 }) 303 this.data.selectNum=4; 304 this.setData({ 305 communityCode:event.currentTarget.dataset.item.code, 306 selectNum:this.data.selectNum, 307 area:this.data.area, 308 communityName:event.currentTarget.dataset.item.name, 309 isHaveSubset:event.currentTarget.dataset.item.isHaveSubset?true:false 310 }) 311 } 312 313 this.setData({ 314 addressObj:{ 315 province:{ 316 'provinceName':this.data.provinceName, 317 'provinceCode':this.data.provinceCode 318 }, 319 city:{ 320 'cityName':this.data.cityName, 321 'cityCode':this.data.cityCode 322 }, 323 area:{ 324 'areaName':this.data.areaName, 325 'areaCode':this.data.areaCode 326 }, 327 address:{ 328 'addressName':this.data.addressName, 329 'addressCode':this.data.addressCode 330 }, 331 community:{ 332 'communityName':this.data.communityName, 333 'communityCode':this.data.communityCode 334 } 335 } 336 }) 337 } 338 } 339 })
1 /* components/area-select.wxssby:张涛20180308 */ 2 .area-select-bg{width:750rpx;height:100%;position:fixed;top:0;left:0;background:rgba(0,0,0,.5);z-index:11;} 3 .area-select-box{width:750rpx;height:800rpx;background:white;position:absolute;bottom:0;left:0;} 4 .area-select-box .area-select-title{width:100%;line-height:80rpx;font-size:30rpx;color:#999999;text-align:center;display:flex;justify-content:space-between;align-items:center;} 5 .area-select-box .area-select-title .select-off{width:100rpx;line-height:80rpx;} 6 .area-select-box .area-select-title .select-on{width:100rpx;line-height:80rpx;color:#ea8842;} 7 .area-select-box .area-select-btn{height:60rpx;display:flex;justify-content:flex-start;align-items:center;position:relative;top:0;left:0;} 8 .area-select-box .area-select-btn .area-select-btn-item{height:56rpx;border-bottom:4rpx solid white;font-size:28rpx;line-height:56rpx;color:#666666;margin:0 10rpx;} 9 .area-select-box .area-select-btn .area-select-btn-active{border-bottom:4rpx solid #ea8842;color:#ea8842;} 10 .area-select-box .area-select-btn:after{content:'';width:100%;height:1rpx;background:#e5e5e5;position:absolute;bottom:0;left:0;} 11 .area-select-box .area-select-show{width:750rpx;height:660rpx;} 12 .area-select-box .area-select-show .area-select-show-item{width:auto;padding:0 26rpx;font-size:28rpx;color:#666666;line-height:76rpx;display:flex;justify-content:flex-start;align-items:center;} 13 .area-select-box .area-select-show .area-select-show-item image{width:28rpx;height:20rpx;margin-left:20rpx;}
自定义组件地址组件,使用第三方地址包,可以任意更改样式,生成符合自己喜好的样式,更加符合项目的需要
使用方式如下
首先需要在wxml中引入 (其中的事件绑定名称可以在组件js中进行修改)
<area-select id="areaSelect" bind:cancelEvent="_cancelEvent" bind:confirmEvent="_confirmEvent"></area-select>
其次需要在引入组件的js中定义该组件(onReady)
this.areaSelect=this.selectComponent("#areaSelect");
最后一点一定要在json文件中添加插件的地址
"usingComponents":{"area-select": "/components/area-select/area-select"}
做完这些后就是在js中绑定好事件
取消事件:_canceEvent
确认事件:_cnnfirmEvent
地址组件的最重要的参数即是 this.areaSelect.data.addressObj
比较重要的一点就是显示地址选择框
this.areaSelect.showDialog();
this.areaSelect.hideDialog();
创作于20180308-by-张涛
知识无止境,追其宗,而归一