前言:
这个功能的实现,中间耽误了几天,在大佬的帮助下终于实现效果,匿名感谢xx大佬
要实现的效果如下:
1、首先需要获取省市区的数据,不考虑后端返数据,自己使用json文件的话,需要获取到完整的中国省市区数据
有个很不错的github源码可供参考,Administrative-divisions-of-China中国行政区划数据,请戳这里进行跳转
我选择的是省市区三级联动数据
github有时很难加载出来,最下面附了完整的数据结构
2、 拿到josn数据后,在uniapp的static文件夹中新建provinceData文件夹,新建provinceData.json文件
没截全,数据太多了
3、然后引入到要使用的页面中
import provinceData from '@/static/provinceData/provinceData.json';
打印出来的效果:
4、然后开始给uviewplus的u-select组件绑数据,vue3是u-picke,
这里遇到个问题,只能说第一次开发,好多点都不懂,u-select只有2x版本才有,我的项目是vue3,需要3x版本,而3x版本里不叫u-select,是u-picker选择器
当我发现u-select使用后效果始终无法出来的时候,我在uni_modules/uview-plus/components文件夹下找是否有u-select,没找到之后我去hbuilderx插件市场搜uview-plus
点进去之后里面有官网文档的链接
打开之后才发现,我之前看的都是2x的版本,说多了都是泪
5、代码解析:
1、3x版是通过show属性控制显示与隐藏
2、columns中接收的是二维数组,需要展示几列,就有几个对应的二维数组
3、如何触发u-picker打开,这里没写,就是在你的点击事件里将data.uselectshow设置为true就行
<u-picker :show="data.uselectshow" ref="uPicker" :columns="provincelist" @confirm="uPickerconfirm" @change="uPickerchangeHandler" @cancel="uCancel"></u-picker>
import {
reactive, ref } from "vue";
import {
onReady, onLoad } from "@dcloudio/uni-app";
import provinceData from '@/static/provinceData/provinceData.json';
let provincelist = reactive([])
let data = reactive({
uselectshow: false,//是否显示所在地
userInfo: {
city: "",//所在地
},
});
onReady(() => {
// 处理省市区数据结构
dealPrinvceData(provinceData)
})
// 处理省市区数据结构,每一步都打印了,具体截图如下:
function dealPrinvceData(data) {
// 所在地初始化地区,默认第一个城市
console.log(data,'data---1');
provincelist[0] = Object.keys(data); //data作为一个对象,取里面的key组成的数组
console.log(provincelist[0],'2');
provincelist[1] = Object.keys(data[provincelist[0][0]]); //data中第一项key对应的value作为一个对象,取对象中的key组成的数组
console.log(provincelist[1],'3');
provincelist[2] = data[provincelist[0][0]][provincelist[1][0]]; //data中第一项key对应的value中的key对应的value
console.log(provincelist[2],'4');
}
data是一个大对象,省是key,对应的value是值
provincelist[0]取data的key,即获取到data的key组成的数组,provincelist[0]打印如下:
provincelist[0]其实是这样的数组,[0: “北京市”,1: “天津市”,2: “河北省”,3: “山西省”,4: “内蒙古自治区”,5: “辽宁省”,6: “吉林省”,7: “黑龙江省”,8: “上海市”,9: “江苏省”,10: “浙江省”,11: “安徽省”,12: “福建省”,13: “江西省”,14: “山东省”,15: “河南省”,16: “湖北省”,17: “湖南省”,18: “广东省”,19: “广西壮族自治区”,20: “海南省”,21: “重庆市”,22: “四川省”,23: “贵州省”,24: “云南省”,25: “西藏自治区”,26: "陕西省"27: “甘肃省”,28: “青海省”,29: “宁夏回族自治区”,30: “新疆维吾尔自治区”]
provincelist[1]取data中第一项key的value中的key,provincelist[0][0] 取的值是北京市,然后data[provincelist[0][0]]指的就是data[‘北京’],Object.keys(data[provincelist[0][0]]) 指的就是data中北京中的key,即市辖区
provincelist[1]打印如下:
provincelist[1]其实是这样的数组,[0:“市辖区”]
provincelist[2]取data中第一项key的value对应的value,即provincelist[0][0] 取的值就是北京市,[provincelist[1][0]取的值就是市辖区,data[provincelist[0][0]][provincelist[1][0]]即data[北京市市辖区]
打印如下:
provincelist[2]其实是这样的数组,[0: “东城区”,1: “西城区”,2: “朝阳区”,3: “丰台区”,4: “石景山区”,5: “海淀区”,6: “门头沟区”,7: “房山区”,8: “通州区”,9: “顺义区”,10: “昌平区”,11: “大兴区”,12: “怀柔区”,13: “平谷区”,14: “密云区”,15: “延庆区”
]
一开始有点懵,想明白了,其实就是处理数据结构的一个过程,将省市区处理成关联性的数据
打印provincelist,结构如下:
onready中只是处理的刚渲染时的效果,当列滚动的时候需要动态处理,即第一列滚动发生变化的时候,第二列和第三列都要改变,改变成第一列对应的市和区
const uPickerchangeHandler = (e) => {
const {
columnIndex,
value,
} = e;
if (columnIndex == 0) {
provincelist[1] = Object.keys(provinceData[value[0]]);
provincelist[2] = provinceData[value[0]][provincelist[1][0]];
}
if (columnIndex == 1) {
provincelist[2] = provinceData[value[0]][value[1]];
}
};
1、打印value的格式如下,当滚动第一列的时候,第二列和第三列都没有变化,我们只取value[0],即拿的是第一列变动的值
Object.keys(provinceData[value[0]]) 翻译下就是获取以对应省为对象,对象中的key组成的数组
以截图的天津市,河北省,山西省举例, provincelist[1]打印的值分别如下:
拿到市的联动数据后,还需要拿区的联动数据 provincelist[2] = provinceData[value[0]][provincelist[1][0]]; 翻译下就是provinceData[xx省xx市],第一列滚动的时候,市和区拿的都是第一个市对应的数据
如果第二列滚动,即代表要选择不同的市,这个时候需要更改区的对应数据,value的第0项和第1项都是正确的,直接获取就行
if (columnIndex == 1) {
provincelist[2] = provinceData[value[0]][value[1]];
}
最终实现效果:
完整josn数据:
{
"北京市": {
"市辖区": ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区",
"密云区", "延庆区"
]
},
"天津市": {
"市辖区": ["和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "东丽区", "西青区", "津南区", "北辰区", "武清区", "宝坻区", "滨海新区", "宁河区",
"静海区", "蓟州区"
]
},
"河北省": {
"石家庄市": ["长安区", "桥西区", "新华区", "井陉矿区", "裕华区", "藁城区", "鹿泉区", "栾城区", "井陉县", "正定县", "行唐县", "灵寿县", "高邑县", "深泽县",
"赞皇县", "无极县", "平山县", "元氏县", "赵县", "石家庄高新技术产业开发区", "石家庄循环化工园区", "辛集市", "晋州市", "新乐市"
],
"唐山市": ["路南区", "路北区", "古冶区", "开平区", "丰南区", "丰润区", "曹妃甸区", "滦南县", "乐亭县", "迁西县", "玉田县", "河北唐山芦台经济开发区", "唐山市汉沽管理区",
"唐山高新技术产业开发区", "河北唐山海港经济开发区", "遵化市", "迁安市", "滦州市"
],
"秦皇岛市": ["海港区", "山海关区", "北戴河区", "抚宁区", "青龙满族自治县", "昌黎县", "卢龙县", "秦皇岛市经济技术开发区", "北戴河新区"],
"邯郸市": ["邯山区", "丛台区", "复兴区", "峰峰矿区", "肥乡区", "永年区", "临漳县", "成安县", "大名县", "涉县", "磁县", "邱县", "鸡泽县", "广平县", "馆陶县",
"魏县", "曲周县", "邯郸经济技术开发区", "邯郸冀南新区", "武安市"
],
"邢台市": ["襄都区", "信都区", "任泽区", "南和区", "临城县", "内丘县", "柏乡县", "隆尧县", "宁晋县", "巨鹿县", "新河县", "广宗县", "平乡县", "威县", "清河县",
"临西县", "河北邢台经济开发区", "南宫市", "沙河市"
],
"保定市": ["竞秀区", "莲池区", "满城区", "清苑区", "徐水区", "涞水县", "阜平县", "定兴县", "唐县", "高阳县", "容城县", "涞源县", "望都县", "安新县", "易县",
"曲阳县", "蠡县", "顺平县", "博野县", "雄县", "保定高新技术产业开发区", "保定白沟新城", "涿州市", "定州市", "安国市", "高碑店市"
],
"张家口市": ["桥东区", "桥西区", "宣化区", "下花园区", "万全区", "崇礼区", "张北县", "康保县", "沽源县", "尚义县", "蔚县", "阳原县", "怀安县", "怀来县",
"涿鹿县", "赤城县", "张家口经济开发区", "张家口市察北管理区", "张家口市塞北管理区"
],
"承德市": ["双桥区", "双滦区", "鹰手营子矿区", "承德县", "兴隆县", "滦平县", "隆化县", "丰宁满族自治县", "宽城满族自治县", "围场满族蒙古族自治县", "承德高新技术产业开发区",
"平泉市"
],
"沧州市": ["新华区", "运河区", "沧县", "青县", "东光县", "海兴县", "盐山县", "肃宁县", "南皮县", "吴桥县", "献县", "孟村回族自治县", "河北沧州经济开发区",
"沧州高新技术产业开发区", "沧州渤海新区", "泊头市", "任丘市", "黄骅市", "河间市"
],
"廊坊市": ["安次区", "广阳区", "固安县", "永清县", "香河县", "大城县", "文安县", "大厂回族自治县", "廊坊经济技术开发区", "霸州市", "三河市"],
"衡水市": ["桃城区", "冀州区", "枣强县", "武邑县", "武强县", "饶阳县", "安平县", "故城县", "景县", "阜城县", "河北衡水高新技术产业开发区", "衡水滨湖新区", "深州市"]
},
"山西省": {
"太原市": ["小店区", "迎泽区", "杏花岭区", "尖草坪区", "万柏林区", "晋源区", "清徐县", "阳曲县", "娄烦县", "山西转型综合改革示范区", "古交市"],
"大同市": ["新荣区", "平城区", "云冈区", "云州区", "阳高县", "天镇县", "广灵县", "灵丘县", "浑源县", "左云县", "山西大同经济开发区"],
"阳泉市": ["城区", "矿区", "郊区", "平定县", "盂县"],
"长治市": ["潞州区", "上党区", "屯留区", "潞城区", "襄垣县", "平顺县", "黎城县", "壶关县", "长子县", "武乡县", "沁县", "沁源县"],
"晋城市": ["城区", "沁水县", "阳城县", "陵川县", "泽州县", "高平市"],
"朔州市": ["朔城区", "平鲁区", "山阴县", "应县", "右玉县", "山西朔州经济开发区", "怀仁市"],
"晋中市": ["榆次区", "太谷区", "榆社县", "左权县", "和顺县", "昔阳县", "寿阳县", "祁县", "平遥县", "灵石县", "介休市"],
"运城市": ["盐湖区", "临猗县", "万荣县", "闻喜县", "稷山县", "新绛县", "绛县", "垣曲县", "夏县", "平陆县", "芮城县", "永济市", "河津市"],
"忻州市": ["忻府区", "定襄县", "五台县", "代县", "繁峙县", "宁武县", "静乐县", "神池县", "五寨县", "岢岚县", "河曲县", "保德县", "偏关县", "五台山风景名胜区",
"原平市"
],
"临汾市": ["尧都区", "曲沃县", "翼城县", "襄汾县", "洪洞县", "古县", "安泽县", "浮山县", "吉县", "乡宁县", "大宁县", "隰县", "永和县", "蒲县", "汾西县",
"侯马市", "霍州市"
],
"吕梁市": ["离石区", "文水县", "交城县", "兴县", "临县", "柳林县", "石楼县", "岚县", "方山县", "中阳县", "交口县", "孝义市", "汾阳市"]
},
"内蒙古自治区": {
"呼和浩特市": ["新城区", "回民区", "玉泉区", "赛罕区", "土默特左旗", "托克托县", "和林格尔县", "清水河县", "武川县", "呼和浩特经济技术开发区"],
"包头市": ["东河区", "昆都仑区", "青山区", "石拐区", "白云鄂博矿区", "九原区", "土默特右旗", "固阳县", "达尔罕茂明安联合旗", "包头稀土高新技术产业开发区"],
"乌海市": ["海勃湾区", "海南区", "乌达区"],
"赤峰市": ["红山区", "元宝山区", "松山区", "阿鲁科尔沁旗", "巴林左旗", "巴林右旗", "林西县", "克什克腾旗", "翁牛特旗", "喀喇沁旗", "宁城县", "敖汉旗"],
"通辽市": ["科尔沁区", "科尔沁左翼中旗", "科尔沁左翼后旗", "开鲁县", "库伦旗", "奈曼旗", "扎鲁特旗", "通辽经济技术开发区", "霍林郭勒市"],
"鄂尔多斯市": ["东胜区", "康巴什区", "达拉特旗", "准格尔旗", "鄂托克前旗", "鄂托克旗", "杭锦旗", "乌审旗", "伊金霍洛旗"],
"呼伦贝尔市": ["海拉尔区", "扎赉诺尔区", "阿荣旗", "莫力达瓦达斡尔族自治旗", "鄂伦春自治旗", "鄂温克族自治旗", "陈巴尔虎旗", "新巴尔虎左旗", "新巴尔虎右旗", "满洲里市",
"牙克石市", "扎兰屯市", "额尔古纳市", "根河市"
],
"巴彦淖尔市": ["临河区", "五原县", "磴口县", "乌拉特前旗", "乌拉特中旗", "乌拉特后旗", "杭锦后旗"],
"乌兰察布市": ["集宁区", "卓资县", "化德县", "商都县", "兴和县", "凉城县", "察哈尔右翼前旗", "察哈尔右翼中旗", "察哈尔右翼后旗", "四子王旗", "丰镇市"],
"兴安盟": ["乌兰浩特市", "阿尔山市", "科尔沁右翼前旗", "科尔沁右翼中旗", "扎赉特旗", "突泉县"],
"锡林郭勒盟": ["二连浩特市", "锡林浩特市", "阿巴嘎旗", "苏尼特左旗", "苏尼特右旗", "东乌珠穆沁旗", "西乌珠穆沁旗", "太仆寺旗", "镶黄旗", "正镶白旗", "正蓝旗", "多伦县",
"乌拉盖管理区管委会"
],
"阿拉善盟": ["阿拉善左旗", "阿拉善右旗", "额济纳旗", "内蒙古阿拉善高新技术产业开发区"]
},
"辽宁省": {
"沈阳市": ["和平区", "沈河区", "大东区", "皇姑区", "铁西区", "苏家屯区", "浑南区", "沈北新区", "于洪区", "辽中区", "康平县", "法库县", "新民市"],
"大连市": ["中山区", "西岗区", "沙河口区", "甘井子区",