前端时间接到一个项目,里面有涉及到地区选择四级联动(即能选择到镇)。自己去网上收罗了一波,也没发现有很详细的,所以就自己来写,写完总结一下。
首先地址选择小程序有自带一个组件,我们就先来看看这个组件:picker组件。
小程序官方用法:
html:
<view class="section">
<view class="section__title">省市区选择器</view>
<picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}">
<view class="picker">
当前选择:{{region[0]}},{{region[1]}},{{region[2]}}
</view>
</picker>
</view>
js
data : {
region: ['广东省', '广州市', '海珠区'],
customItem: '全部',
}
用了以后我们看到,只有三级联动,无奈甲方他不予许呀,一定要是四级联动。
所以我们还是老老实实得写四级联动。
准备工作,首先我们得有一个json文件,包含了中国省,市、县,镇。
我在网上找了一波,终于找到一位大佬爬出来的(重点是免费的,找了好多都要收什么费用)这是大佬的github地址
我用的是下面的这个:
这个我们只是测试,所以我就用vs code 开一个php服务器,把json文件放到服务器里面,通过掉接口的形式来调用。
然后开启php服务。然后在当前文件夹下开启php服务(vs code 安装运行php环境才能跑起来)
然后我们回到小程序,先调我们本地接口,看看接口是否通:
getSiteData: function() {
var that = this;
wx.request({
url: 'http://localhost:3000/index.php', // 这是我们本地的地址
success: res=> {
console.log(res); // 输出接口的回调
}
})
}
ok,现在数据返回成功了。
我们开始写联动部分
还是picker组件,利用其多列选择器 mode = multiSelector。先看看官方使用:
<view class="section"> <view class="section__title">多列选择器</view> <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}" > <view class="picker"> 当前选择:{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}} </view> </picker> </view>
data: { array: ['美国', '中国', '巴西', '日本'], objectArray: [ { id: 0, name: '美国' }, { id: 1, name: '中国' }, { id: 2, name: '巴西' }, { id: 3, name: '日本' } ], index: 0, multiArray: [['无脊柱动物', '脊柱动物'], ['扁性动物', '线形动物', '环节动物', '软体动物', '节肢动物'], ['猪肉绦虫', '吸血虫']], objectMultiArray: [ [ { id: 0, name: '无脊柱动物' }, { id: 1, name: '脊柱动物' } ], [ { id: 0, name: '扁性动物' }, { id: 1, name: '线形动物' }, { id: 2, name: '环节动物' }, { id: 3, name: '软体动物' }, { id: 3, name: '节肢动物' } ], [ { id: 0, name: '猪肉绦虫' }, { id: 1, name: '吸血虫' } ] ], multiIndex: [0, 0, 0], date: '2016-09-01', time: '12:01', region: ['广东省', '广州市', '海珠区'], customItem: '全部' },
里面的属性值 range接受一个数组,数组里面包含数组,数组长度就是多少列,我们是四级联动,所以我们就需要按这样的格式来赋值[[省数组],[市数组],[县数组],[镇数组]]。
根据我们的接口回调数据结构,我们就写了一串获取省市县镇的js代码
getSiteData: function() {
var that = this;
wx.request({
url: 'http://localhost:3000/index.php',
success: res=> {
console.log(res);
var chinaData = res.data;
this.data.chinaData = chinaData;
var sheng = []; // 设置省数组
for(var i = 0; i < chinaData.length; i++) {
sheng.push(chinaData[i].name);
}
this.setData({
"multiArray[0]": sheng
})
that.getCity(); // 得到市
}
})
},
getCity: function() { // 得到市
var shengNum = this.data.multiIndex[0];
var chinaData = this.data.chinaData;
var cityData = chinaData[shengNum].children;
var city = [];
for (var i = 0; i < cityData.length; i++) {
city.push(cityData[i].name)
}
this.setData({
"multiArray[1]": city
})
this.getXian();
},
getXian: function(e) { // 得到县
var shengNum = this.data.multiIndex[0];
var cityNum = this.data.multiIndex[1];
var chinaData = this.data.chinaData;
var xianData = chinaData[shengNum].children[cityNum].children;
var xian = [];
for (var i = 0; i < xianData.length; i++) {
xian.push(xianData[i].name)
}
this.setData({
"multiArray[2]": xian
})
this.getZhen();
},
getZhen: function() { // 得到镇
var shengNum = this.data.multiIndex[0];
var cityNum = this.data.multiIndex[1];
var xianNum = this.data.multiIndex[2];
var chinaData = this.data.chinaData;
var zhenData = chinaData[shengNum].children[cityNum].children[xianNum].children;
var zhen = [];
for (var i = 0; i < zhenData.length; i++) {
zhen.push(zhenData[i].name)
}
this.setData({
"multiArray[3]" : zhen
})
}
下面就是所有的代码:
wxml代码
<view class='site'>
<view class="section">
<view class="section__title">省市区选择器</view>
<picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}">
<view class="picker">
当前选择:{{region[0]}},{{region[1]}},{{region[2]}}
</view>
</picker>
</view>
<view class="section">
<view class="section__title">多列选择器</view>
<picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
<view class="picker" style='font-size:24rpx'>
当前选择:{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}},{{multiArray[3][multiIndex[3]]}}
</view>
</picker>
</view>
</view>
js代码:
// pages/demo/site/site.js
Page({
/**
* 页面的初始数据
*/
data: {
region: ['广东省', '广州市', '海珠区'],
customItem: '全部',
multiArray: [],
multiIndex: [0, 0, 0, 0],
chinaData: []
},
bindDateChange(e) {
console.log('picker发送选择改变,携带值为', e.detail.value)
this.setData({
date: e.detail.value
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getSiteData();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
bindMultiPickerChange: function(e) {
console.log(e);
},
bindMultiPickerColumnChange: function(e) {
var move = e.detail;
var index = move.column;
var value = move.value;
if (index == 0) {
this.setData({
multiIndex: [value,0,0,0]
})
this.getCity();
}
if (index == 1) {
this.setData({
"multiIndex[1]": value,
"multiIndex[2]": 0,
"multiIndex[3]": 0
})
this.getXian();
}
if (index == 2) {
this.setData({
"multiIndex[2]": value,
"multiIndex[3]": 0,
})
this.getZhen();
}
if (index == 3) {
this.setData({
"multiIndex[3]": value
})
this.getZhen();
}
},
getSiteData: function() {
var that = this;
wx.request({
url: 'http://localhost:3000/index.php',
success: res=> {
console.log(res);
var chinaData = res.data;
this.data.chinaData = chinaData;
var sheng = []; // 设置省数组
for(var i = 0; i < chinaData.length; i++) {
sheng.push(chinaData[i].name);
}
this.setData({
"multiArray[0]": sheng
})
that.getCity(); // 得到市
}
})
},
getCity: function() { // 得到市
var shengNum = this.data.multiIndex[0];
var chinaData = this.data.chinaData;
var cityData = chinaData[shengNum].children;
var city = [];
for (var i = 0; i < cityData.length; i++) {
city.push(cityData[i].name)
}
this.setData({
"multiArray[1]": city
})
this.getXian();
},
getXian: function(e) { // 得到县
var shengNum = this.data.multiIndex[0];
var cityNum = this.data.multiIndex[1];
var chinaData = this.data.chinaData;
var xianData = chinaData[shengNum].children[cityNum].children;
var xian = [];
for (var i = 0; i < xianData.length; i++) {
xian.push(xianData[i].name)
}
this.setData({
"multiArray[2]": xian
})
this.getZhen();
},
getZhen: function() { // 得到镇
var shengNum = this.data.multiIndex[0];
var cityNum = this.data.multiIndex[1];
var xianNum = this.data.multiIndex[2];
var chinaData = this.data.chinaData;
var zhenData = chinaData[shengNum].children[cityNum].children[xianNum].children;
var zhen = [];
for (var i = 0; i < zhenData.length; i++) {
zhen.push(zhenData[i].name)
}
this.setData({
"multiArray[3]" : zhen
})
}
})
真尴尬,现在才发现这个插入代码功能。
(测试本地接口记得小程序开发工具打开不校验合法域名,这样才能调接口成功。如果有什么问题,记得及时联系我哦)
下面附上GitHub代码地址: