最近接触小程序,使用微信自带的省市区选择器,发现无法满足需求,原因是后台需要省市区国标码发送接口查询数据,微信自带的省市区选择器只有Name,没有国标码,所以只能自定义省市区三级联动选择器,废话不多说,直接上代码。
参考文档:https://www.cnblogs.com/xjwy/p/6681867.html?utm_source=tuicool&utm_medium=referral
代码如下:
一、定义模板:
template.wxml代码如下:
<template name="cascade">
<view class="cascade_box" animation="{{animationData}}">
<view class="cascade_hei"></view>
<view class="cascade_find">
<view class="cascade_header">
<text class='quxiao' catchtap="cancel">取消</text>
<text class="queren" catchtap="confirm">确认</text>
</view>
<picker-view indicator-style="height: 80rpx;" style="width: 100%; height: 500rpx;" bindchange="bindChange">
<picker-view-column>
<view wx:for="{{provinces}}" wx:key='id' style="line-height: 80rpx;text-align:center;">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{citys}}" wx:key='id' style="line-height: 80rpx;text-align:center;">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{areas}}" wx:key='id' style="line-height: 80rpx;text-align:center;">{{item.name}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
</template>
template.wxss样式代码如下:
.cascade_box {
font-size: 28rpx;
width: 100%;
height: 0;
position: fixed;
bottom: 0;
left: 0;
z-index: 4;
}
.cascade_hei {
width: 100%;
height: 732rpx;
background: #000;
opacity: 0.5;
z-index: 4;
}
.cascade_find {
width: 100%;
height: 500rpx;
position: relative;
background: #fff;
z-index: 4;
}
.quxiao, .queren {
margin: 0rpx 30rpx;
font-weight:bold;
font-size: 35rpx;
display: block;
position: absolute;
width: 100rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
z-index: 4;
}
.quxiao {
color: #969696;
z-index: 4;
}
.queren {
right: 0;
top: 0;
color: #59C458;
z-index: 4;
}
.cascade_header {
border-bottom: 2rpx solid #f8f8f8;
height: 80rpx;
width: 100%;
margin-bottom: 20rpx;
z-index: 4;
}
二、省市联动开始
houseInfo.wxml代码如下:
<import src="../template/template.wxml" />
<template is="cascade" data="{{animationData:animationData,provinces:provinces,citys:citys,areas:areas}}"/>
<view class="page-section">
<view class="weui-cells weui-cells_after-title">
<!--房产区域-->
<view class="weui-cell weui-cell_input">
<view class="weui-cell__hd">
<view class="weui-label">房产区域</view>
</view>
<view class="weui-cell__bd">
<input bindtap="provincesCitysClick" class='weui-input' disabled='true' name="HouseRegion" value='{{result.provinces.name}}{{result.citys.name}}{{result.areas.name}}'></input>
</view>
</view>
</view>
</view>
houseInfo.wxss代码如下:
@import '../template/template.wxss';
.table {
background-color: #FFFFFF;
/* padding:0rpx 50rpx; */
margin-right:50rpx;
}
.tr {
border-top: 1rpx solid #D9D9D9;
margin-left:50rpx;
display: flex;
width: 100%;
height: 3rem;
align-items: center;
font-size: 35rpx;
font-family:"SimSun";
color: #6C6C6C;
}
.btnCode1{
border-radius:20rpx;
height:70rpx;
min-height: 0em;
line-height: 0em;
width: 100%;
background-color:#08CBFF;
text-align:center;
border:2rpx solid #08CBFF;
}
.btnCode2{
border-radius:20rpx;
height:70rpx;
min-height: 0em;
line-height: 0em;
width: 100%;
background-color:#FFFFFF;
text-align:center;
border:2rpx solid #08CBFF;
}
.btnTextColor1{
color: #FFFFFF;
text-align: center;
font-size: 30rpx;
margin: 40rpx 0rpx 20rpx 0rpx;
}
.btnTextColor2{
color: #08CBFF;
text-align: center;
font-size: 30rpx;
margin: 40rpx 0rpx 20rpx 0rpx;
}
.hide{
display: none;
}
.show{
display: block;
}
.page-head-title{
display: inline-block;
padding: 20rpx 20rpx 20rpx 20rpx;
font-size: 32rpx;
color: #BEBEBE;
}
houseInfo.js代码如下:
var qgData = require('../utils/quanguo.js');
Page({
data: {
province_index: 0,//picker-view省项选择的value值
city_index: 0,//picker-view市项选择的value值
area_index: 0,//picker-view区项选择的value值
},
/**
* 省市区下拉框点击事件
* 点击弹出选择页
* 选择页为动画效果
*/
provincesCitysClick: function () {
//这里写了一个动画,让其高度变为满屏
var animation = wx.createAnimation({
duration: 300,
timingFunction: 'ease',
})
this.animation = animation
animation.height(1332 + 'rpx').step()
this.setData({
animationData: animation.export()
})
},
/**
* 省市区下拉框取消事件
* 取消事件为动画效果
* 修改选择页高度为0
* 同时把选择结果集合清空
*/
cancel: function () {
//这里也是动画,然其高度变为0
var animation = wx.createAnimation({
duration: 300,
timingFunction: 'ease',
})
this.animation = animation
animation.height(0 + 'rpx').step()
this.setData({
isShow: true,
animationData: animation.export()
});
},
/**
* 省市区下拉框确认事件
* 确认事件为动画效果 与取消动画效果一致 高度设置为0
* 但是要加载下拉框选中的数据赋给结果集合
*/
confirm: function () {
//一样是动画,级联选择页消失,效果和取消一样
var animation = wx.createAnimation({
duration: 300,
timingFunction: 'ease',
})
this.animation = animation
animation.height(0 + 'rpx').step()
this.setData({
isShow: false,
animationData: animation.export(),
addressResult: ""
});
this.cascade();
},
/**
* 省市区下拉框滚动触发事件
* 级联加载对应数据
* 并把选中的省市区关联数据放入结果集合
* 以便点击确认按钮是显示对应结果
*/
bindChange: function (e) {
//这里是获取picker-view内的picker-view-column 当前选择的是第几项
const val = e.detail.value
this.setData({
province_index: val[0],
city_index: val[1],
area_index: val[2],
})
this.cascade();
},
/**
* 级联省市区方法
* 根据所选择的省、市加载对应的数据
* 同时把所选中的省市区放入结果集合
*/
cascade: function () {
var that = this;
var provincesCitys = qgData.data.regions;
var provinces = [];
var citys = [];
var areas = [];
var area_index = that.data.area_index;
var city_index = that.data.city_index;
var province_index = that.data.province_index;
if (JSON.stringify(provincesCitys) != "{}") {
//遍历所有的数据,将省的信息存到provinces这个数组中
for (let i = 0; i < provincesCitys.length; i++) {
provinces.push(provincesCitys[i])
}
if (provincesCitys[province_index].regions) {//这里判断这个省级里面有没有市(如数据中的香港、澳门等就没有写市)
if (provincesCitys[province_index].regions[city_index]) {//这里是判断这个选择的省里面,有没有相应的下标为city_index的市,因为这里的下标是前一次选择后的下标,比如之前选择的一个省有10个市,我刚好滑到了第十个市,现在又重新选择了省,但是这个省最多只有5个市,但是这时候的city_index为9,而这里的市根本没有那么多,所以会报错
//这里如果有这个市,那么把选中的这个省中的所有的市的名字保存到citys这个数组中
for (let i = 0; i < provincesCitys[province_index].regions.length; i++) {
citys.push(provincesCitys[province_index].regions[i]);
}
if (provincesCitys[province_index].regions[city_index].regions) {//这里是判断选择的这个市在数据里面有没有区县
if (provincesCitys[province_index].regions[city_index].regions[area_index]) {//这里是判断选择的这个市里有没有下标为area_index的区县,道理同上面市的选择
for (let i = 0; i < provincesCitys[province_index].regions[city_index].regions.length; i++) {
areas.push(provincesCitys[province_index].regions[city_index].regions[i]);
}
} else {
//这里和选择市的道理一样
that.setData({
area_index: 0
});
for (let i = 0; i < provincesCitys[province_index].regions[city_index].regions.length; i++) {
areas.push(provincesCitys[province_index].regions[city_index].regions[i]);
}
}
} else {
//如果这个市里面没有区县,那么把这个市的名字就赋值给area这个数组
areas.push(provincesCitys[province_index].regions[city_index]);
}
} else {
//如果选择的省里面没有下标为city_index的市,那么把这个下标的值赋值为0;然后再把选中的该省的所有的市的名字放到citys这个数组中
that.setData({
city_index: 0
});
for (let i = 0; i < provincesCitys[province_index].regions.length; i++) {
citys.push(provincesCitys[province_index].regions[i]);
}
}
} else {
//如果该省级没有市,那么就把省的名字作为市和区的名字
citys.push(provincesCitys[province_index]);
areas.push(provincesCitys[province_index]);
}
//选择成功后把相应的数组赋值给相应的变量
that.setData({
provinces: provinces,
citys: citys,
areas:areas,
});
//有时候网络慢,会出现区县选择出现空白,这里是如果出现空白那么执行一次回调
if (provinces.length == 0 || citys.length == 0) {
that.cascade();
console.log('执行回调函数cascade(),再次加载省市区');
}
//把选择的省市区都放到result中
let result = {
provinces: provinces[that.data.province_index],
citys: citys[that.data.city_index],
areas:areas[that.data.area_index],
};
that.setData({
result: result,
});
}
},
onLoad: function () {
var that = this;
that.cascade();
}
})
注:quanguo.js文件路径如下:quanguo.js