小程序自定义组件之省市区地址三级联动

wxml结构图如下

 1 <!--components/ares/area.wxml-->
 2 <!-- 自定义地图插件用于使用第三方地图数据包 by张涛20180307 -->
 3 <view class="area-box" wx:if="{{isShow}}" data-address="{{address}}">
 4     <view class="area-btn">
 5         <view class="area-btn-off" catchtap='_cancelEvent' >取消</view>
 6         <view class="area-btn-on" catchtap='_confirmEvent'>确认</view>
 7     </view>
 8   <picker-view indicator-style="height:50px;" style="width:750rpx; height:200px;" value="{{value}}" bindchange="bindChange">
 9     <picker-view-column>
10       <view wx:for="{{area.province}}" wx:key='' style="line-height: 50px;text-align:center;">{{item.name}}</view>
11     </picker-view-column>
12     <picker-view-column>
13       <view wx:for="{{area.city}}" wx:key='' style="line-height: 50px;text-align:center">{{item.name}}</view>
14     </picker-view-column>
15     <picker-view-column>
16       <view wx:for="{{area.area}}" wx:key='' style="line-height: 50px;text-align:center">{{item.name}}</view>
17     </picker-view-column>
18   </picker-view>
19 </view>

json包如下

 1 { 2 "component":true, 3 "usingComponents":{} 4 } 

wxss样式图如下

1 /*自定义地图插件用于使用第三方地图数据包 by张涛20180307*/
2 .area-box{position:fixed;bottom:0;left:0;background:white;box-shadow:0 0 10px 10px #f2f2f2;}
3 .area-btn{width:100%;height:80rpx;font-size:28rpx;display:flex;justify-content:space-between;align-items:center;border-bottom:2rpx solid #ff9f09;}
4 .area-btn .area-btn-off{width:140rpx;line-height:80rpx;text-align:center;}
5 .area-btn .area-btn-on{width:140rpx;line-height:80rpx;color:#ff9f09;text-align:center;}

js代码如下

1 // 自定义地图插件用于使用第三方地图数据包 by张涛20180307
  2 // components/Dialog/dialog.js
  3 const util = require('../../utils/request.js');
  4 Component({
  5   options: {
  6     multipleSlots: true // 在组件定义时的选项中启用多slot支持
  7   },
  8   /**
  9    * 组件的属性列表
 10    * 用于组件自定义设置
 11    */
 12   properties: {
 13     // 模拟数据
 14     provinces: {            // 属性名
 15       type: Array,     // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
 16       value:[{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000}]     // 属性初始值(可选),如果未指定则会根据类型选择一个
 17     },
 18     citys: {            // 属性名
 19       type: Array,     // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
 20       value:[{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000}]     // 属性初始值(可选),如果未指定则会根据类型选择一个
 21     },
 22     areas: {            // 属性名
 23       type: Array,     // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
 24       value:[{'name':"丰台区",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000},{'name':"北京",'code':1000000}]     // 属性初始值(可选),如果未指定则会根据类型选择一个
 25     }
 26   },
 27 
 28   /**
 29    * 私有数据,组件的初始数据
 30    * 可用于模版渲染
 31    */
 32   data: {
 33     // 弹窗显示控制
 34     isShow:false,
 35     value:'',
 36     area:{
 37       province:[],
 38       city:[],
 39       area:[]
 40     },
 41     provinceCode:'',
 42     cityCode:'',
 43     areaCode:'',
 44     address:{
 45       province:'',
 46       city:'',
 47       area:''
 48     },
 49     // 滚动地址后的最后位置点
 50     areaList:[]
 51   },
 52   /*
 53   *组件生命周期函数,在组件实例进入页面节点树时执行
 54   */
 55   attached:function(){
 56     this.getProvince();
 57   },
 58   /**
 59    * 组件的方法列表
 60    * 更新属性和数据的方法与更新页面数据的方法类似
 61    */
 62   methods: {
 63     /*
 64      * 公有方法
 65      */
 66      // 地址三级请求函数
 67      //
 68      getProvince(){
 69       var _this=this;
 70       util.POST('/mobile/common/getArea','',{'parentCode':this.data.provinceCode},function(res){
 71         _this.data.area.province=res.data.result;
 72         _this.setData({
 73           area:_this.data.area,
 74           provinceCode:res.data.result[0].code
 75         })
 76         _this.getCity();
 77       })
 78      },
 79     //
 80      getCity(){
 81       var _this=this;
 82       util.POST('/mobile/common/getArea','',{'parentCode':this.data.provinceCode},function(res){
 83           _this.data.area.city=res.data.result;
 84           _this.setData({
 85             area:_this.data.area,
 86             cityCode:res.data.result[0].code
 87           })
 88           _this.getArea();
 89       })
 90      },
 91      //
 92      getArea(){
 93       var _this=this;
 94       util.POST('/mobile/common/getArea','',{'parentCode':this.data.cityCode},function(res){
 95         _this.data.area.area=res.data.result;
 96         _this.setData({
 97             area:_this.data.area,
 98             areaCode:res.data.result[0].code,
 99             address:{
100               province:_this.data.area.province[_this.data.areaList[0]?_this.data.areaList[0]:0],
101               city:_this.data.area.city[_this.data.areaList[1]?_this.data.areaList[1]:0],
102               area:_this.data.area.area[_this.data.areaList[2]?_this.data.areaList[2]:0]
103             }
104         })
105       })
106      },
107     //隐藏弹框
108     hideDialog(){
109       this.setData({
110         isShow: !this.data.isShow
111       })
112     },
113     //展示弹框
114     showDialog(){
115       this.setData({
116         isShow: !this.data.isShow
117       })
118     },
119      /*
120      * 内部私有方法建议以下划线开头
121      * triggerEvent 用于触发事件
122      */
123     _cancelEvent(){
124       //触发取消回调
125       this.triggerEvent("cancelEvent")
126     },
127     _confirmEvent(){
128       //触发成功回调
129       this.triggerEvent("confirmEvent");
130     },
131     bindChange(event){
132       // 保存滚动按钮坐标
133       this.setData({
134         areaList:event.detail.value
135       })
136       if (this.data.provinceCode!=this.data.area.province[event.detail.value[0]].code) {
137         // 改动了省,修改省的代码
138         this.setData({
139           provinceCode:this.data.area.province[event.detail.value[0]].code
140         })
141         this.getCity();
142       }
143       if (this.data.cityCode!=this.data.area.city[event.detail.value[1]].code) {
144         // 改动了省,修改省的代码
145         this.setData({
146           cityCode:this.data.area.city[event.detail.value[1]].code
147         })
148         this.getArea();
149       }
150       if (this.data.areaCode!=this.data.area.area[event.detail.value[2]].code) {
151         // 改变了区的选择
152         this.setData({
153           address:{
154             province:this.data.area.province[event.detail.value[0]],
155             city:this.data.area.city[event.detail.value[1]],
156             area:this.data.area.area[event.detail.value[2]]
157           }
158         })
159       }
160     },
161   }
162 })
163 
164 
165 // 使用说明使用在你需要此组件的文件中引入,引入方式如下
166 // wxml中引入方式
167 // <area id="area" bind:cancelEvent="_cancelEvent"  bind:confirmEvent="_confirmEvent"></area>
168 // 其中_cancelEvent为取消按钮
169 // _confirmEvent为确认按钮
170 // js中定义方式
171 // this.area = this.selectComponent("#area");
172 // 在json中定义方式
174 //   "usingComponents": {
175 //     "area": "/components/area/area"
176 //   }
177 // }
178 // by张涛20180307

 

 

思路来源于以下文章

新手小程序自定义组件教程

posted @ 2018-03-07 16:51  BlueSky1024  阅读(900)  评论(0编辑  收藏  举报