1,小程序有内置的picker地区选择器,但更希望选择地区后直接传递省市id,所以我使用的多列选择器。
2,多列选择器有两种方法,一种小程序只存储省的数据,因省数据较少。选择省后request请求获得对应省的市数据。
3,我采用的是将省市数据在小程序加载时都存储到小程序。
4,不同页面省市一致的问题。
5,地理定位。
province.js、city.js
如何生成省市json数据?在此不做介绍。示例如下。
//province.js
var provinceData =[{"id":"0","name":"全国"},{"id":"1","name":"北京"},{"id":"2","name":"上海"},{"id":"3","name":"天津"},{"id":"4","name":"重庆"},{"id":"5","name":"河北"},{"id":"6","name":"山西"},{"id":"7","name":"内蒙古"},{"id":"8","name":"辽宁"},{"id":"9","name":"吉林"},{"id":"10","name":"黑龙江"},{"id":"11","name":"江苏"},{"id":"12","name":"浙江"},{"id":"13","name":"安徽"},{"id":"14","name":"福建"},{"id":"15","name":"江西"},{"id":"16","name":"山东"},{"id":"17","name":"河南"},{"id":"18","name":"湖北"},{"id":"19","name":"湖南"},{"id":"20","name":"广东"},{"id":"21","name":"广西"},{"id":"22","name":"海南"},{"id":"23","name":"四川"},{"id":"24","name":"贵州"},{"id":"25","name":"云南"},{"id":"26","name":"西藏"},{"id":"27","name":"陕西"},{"id":"28","name":"甘肃"},{"id":"29","name":"宁夏"},{"id":"30","name":"青海"},{"id":"31","name":"新疆"},{"id":"32","name":"香港"},{"id":"33","name":"澳门"},{"id":"34","name":"台湾"}];
export default provinceData;
市数据,数组下标为省id,这里仍然需要自己组装。json数组是看不出来的,当小程序加载出来后会有很多NULL,空下标,因为省数据不一定是连续的id,这里我也没想到好的方法。示例如下,因数据较多,省略大部分。
//city.js
var cityData =[[{"pid":"0","id":"0","name":"不限"}],[{"pid":"1","id":"0","name":"不限"},{"pid":"1","id":"1","name":"东城"},{"pid":"1","id":"2","name":"西城"},{"pid":"1","id":"3","name":"崇文"},{"pid":"1","id":"4","name":"宣武"},{"pid":"1","id":"5","name":"朝阳"},{"pid":"1","id":"6","name":"丰台"},{"pid":"1","id":"7","name":"石景山"},{"pid":"1","id":"8","name":"海淀"},{"pid":"1","id":"9","name":"门头沟"},{"pid":"1","id":"10","name":"房山"},{"pid":"1","id":"11","name":"通州"},{"pid":"1","id":"12","name":"顺义"},{"pid":"1","id":"13","name":"昌平"},{"pid":"1","id":"14","name":"大兴"},{"pid":"1","id":"15","name":"平谷"},{"pid":"1","id":"16","name":"怀柔"},{"pid":"1","id":"17","name":"密云"},{"pid":"1","id":"18","name":"延庆"}],[{"pid":"2","id":"0","name":"不限"}.....................{"pid":"2","id":"19","name":"崇明"}]];
export default cityData;
页面逻辑
我用的是uni-app开发,可能语法和原生有些不同,但不会差异很大。
页面显示
<picker mode="multiSelector" @change="bindCityPickerChange" @columnchange="bindCityPickerColumnChange" :value="cityIndex" :range="cityArray" :range-key="'name'">
{{cityArray[0][cityIndex[0]].name}}-{{cityArray[1][cityIndex[1]].name}}
</picker>
js部分
import provinceData from '../../common/province.js';
import cityData from '../../common/city.js';
var _self;
export default{
data() {
return {
//省市数据
cityId:[0,0],
cityIndex: [0,0],
cityArray:[[],[]],
}
},
onLoad() {
_self = this; //对象重命名
this.cityInit();
},
methods:{
/*城市初始化*/
cityInit:function(){
this.getStorge(); //同步其他页面的省市
this.getCityByIndex();
//this.debug();
},
/*获取缓存中的地理索引*/
getStorge:function(){
try {
var cityIndex = uni.getStorageSync('cityIndex');
if (cityIndex) {
this.cityIndex = cityIndex;
}else{
this.cityLocation(); //仅在需要定位的页面使用
}
console.log('getstroge',this.cityIndex);
} catch (e) {
console.log(e);
}
},
/*设置缓存*/
setStorge:function(key,value){
try {
uni.setStorageSync(key, value);
} catch (e) {
console.log(e);
}
},
/*根据索引获取数据*/
getCityByIndex:function(){
var cityIndex = this.cityIndex; //已知
var cityId = this.cityId;
var cityArray = this.cityArray;
cityId[0] = provinceData[this.cityIndex[0]].id; // 省id
var c_arr = cityData[ cityId[0] ]; // 市数组
cityId[1] = c_arr[cityIndex[1]].id; // 市id
this.cityId = cityId;
this.cityArray = [provinceData,c_arr];
console.log('getcitybyindex');
//this.debug();
},
/*地区列改变*/
bindCityPickerColumnChange:function(e){
var column = e.detail.column; // 列:0是父类 1是子类
var value = e.detail.value; // 数组下标
this.cityIndex.splice(column, 1, value); //splice(要替换的数组下标,1为替换,更改的值)
//如果改变的是父类的列
if( column == 0 ){
var province_id = provinceData[value].id; //省id
this.cityArray.splice(1, 1, cityData[province_id]);
this.cityIndex.splice(1, 1, 0);
}
},
/*选中后城市变化*/
bindCityPickerChange:function(e){
var result = e.detail.value;
this.cityIndex = result;
var province_id = provinceData[result[0]].id;
var city_id = this.cityArray[1][result[1]].id;
this.cityId = [province_id,city_id];
this.setStorge('cityIndex',this.cityId); //存入stroge达到不同页面同步的目的
//进行自定义逻辑
},
/*
* 地理定位
*/
cityLocation:function(){
uni.getLocation({
type: 'wgs84',
altitude: false,
success: res => {
console.log(res);//这里res返回的是省市名称,去数据库查询,返回省市id
var params = {province:res.province, city:res.city, district:res.district};
//这里我用了封装的http类,可用原生代替
_self.$http.get('url',params)
.then(function (response) {
console.log(response);
if(response.code== 0){
//成功
_self.setStorge('cityIndex',[response.province_id,response.city_id]);
_self.cityInit();
//自定义逻辑
}else{
console.log('没有查找到该地区');
}
}).catch(function (error) {
console.log(error);
});
},
fail: err => {
console.log('未授权,定位失败');
},
complete: () => {
console.log('获取地理定位完成');
}
});
},
debug:function(){
console.log( this.cityId);
console.log( this.cityIndex);
console.log( this.cityArray);
}
}
}