目录
先看效果,这里以移动端为例
pc端稍微改下标签名和样式即可使用。
一、省市区街道选择器弹窗组件代码
html
<template>
<view class="page-content" :style="{'--color':color}">
<!-- 选择器背景 -->
<view class="page-mask"></view>
<!-- 选择器主体 -->
<view class="page-main" :style="'height:60%'">
<!-- 操作区域 包含取消和确定 -->
<view class="main-operate">
<text class="title-txt" @click.stop="handleCancel">取消</text>
<text class="title-txt" @click.stop="handleSubmit">确定</text>
</view>
<!-- 已选择的地址信息 -->
<view class="main-select">
<text v-if="showIndex == 0 || provinceObj.fullname" :class="showIndex == 0 ? 'select' : ''"
@click="anewSelect(0)">{{ provinceObj.fullname || "请选择" }}</text>
<text v-if="showIndex == 1 || cityObj.fullname" :class="showIndex == 1 ? 'select' : ''"
@click="anewSelect(1)">{{ cityObj.fullname || "请选择" }}</text>
<text v-if="showIndex == 2 || areaObj.fullname" :class="showIndex == 2 ? 'select' : ''"
@click="anewSelect(2)">{{ areaObj.fullname || "请选择" }}</text>
<text v-if="(showIndex == 3 || streetObj.fullname) && selectAreaLevelLimit == 4"
:class="showIndex == 3 ? 'select' : ''"
@click="anewSelect(3)">{{ streetObj.fullname || "请选择" }}</text>
</view>
<!-- 待选择的地址信息 -->
<view class="maincom">
<view v-if="showIndex == 0" class="main-list">
<view class="list-box" :class="provinceObj.id == item.id ? 'active' : ''"
@click="handleSelectAddress(0, item)" v-for="item in provinceData" :key="item.id">
<text>{{ item.fullname }}</text>
</view>
</view>
<view v-if="showIndex == 1" class="main-list">
<view class="list-box" :class="cityObj.id == item.id ? 'active' : ''"
@click="handleSelectAddress(1, item)" v-for="item in cityData" :key="item.id">
<text>{{ item.fullname }}</text>
</view>
</view>
<view v-if="showIndex == 2" class="main-list">
<view class="list-box" :class="areaObj.id == item.id ? 'active' : ''"
@click="handleSelectAddress(2, item)" v-for="item in areaData" :key="item.id">
<text>{{ item.fullname }}</text>
</view>
</view>
<view v-if="showIndex == 3 && selectAreaLevelLimit == 4" class="main-list">
<view class="list-box" :class="streetObj.id == item.id ? 'active' : ''"
@click="handleSelectAddress(3, item)" v-for="item in streetsData" :key="item.id">
<text>{{ item.fullname }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
js
<script>
export default {
name: "UniAddressSelector",
props: {
},
data() {
return {
color: "#0068b7",
showIndex: 0, //地区显示
provinceObj: {},//当前选择的省份对象
cityObj: {},
areaObj: {},
streetObj: {},
heightCot: 30, //设置屏幕高度 0 ~ 100
provinceData: [], // 当前展示的省数据
cityData: [], // 当前展示的市数据
areaData: [], //当前展示的区数据
streetsData: [], //当前展示的区数据
selectAreaLevelLimit: 4,//层级:省市区街道=4
};
},
mounted() {
this.handleGetMap();
},
onShow() {},
methods: {
//取消
handleCancel() {
this.$emit("cancel");
},
//确定
handleSubmit() {
const {
provinceObj,
cityObj,
areaObj,
streetObj
} = this;
const arr = [provinceObj, cityObj, areaObj, streetObj];
let _fullAreaText = [];
arr.map((item) => {
if (item.id) {
_fullAreaText.push(item.fullname);
}
});
if (_fullAreaText.length !== this.selectAreaLevelLimit) {
uni.showToast({
icon: "none",
title: "地址需精确到街道",
});
return
}
let areaInfoObj = {
fullAreaTextInitial: _fullAreaText.toString(),
fullAreaText: _fullAreaText.toString().replace(/,/g, "-"),
provinceCode: provinceObj.id || "",
cityCode: cityObj.id || "",
id: areaObj.id || "",
streetCode: streetObj.id || "",
provinceObj,
cityObj,
areaObj,
streetObj,
};
this.$emit("confirm", areaInfoObj);
},
//下拉选择
anewSelect(num) {
switch (num) {
case 0:
this.showIndex = 0;
this.cityObj = {};
this.areaObj = {};
this.streetObj = {};
this.cityData = [];
this.areaData = [];
this.streetsData = [];
break;
case 1:
this.showIndex = 1;
this.streetObj = {};
this.areaData = [];
this.streetsData = [];
if (!this.areaObj.id) return;
this.areaObj = {};
break;
case 2:
this.showIndex = 2;
this.streetsData = [];
if (!this.streetObj.id) return;
this.streetObj = {};
break;
case 3:
break;
}
},
handleGetMap() {
uni.request({
url: 'https://apis.map.qq.com/ws/district/v1/list', //腾讯地图获取省市区列表接口,接口文档https://lbs.qq.com/service/webService/webServiceGuide/search/webServiceDistrict
data: {
key: '填写您自己在腾讯地图申请的key',
struct_type: 1,//以省市区实际归属进行嵌套的结构返回
},
success: (res) => {
if (res.data.status == 0) {
console.log(res.data);
this.provinceData = res.data.result
} else {
uni.showToast({
icon: "none",
title: res.data.message,
position: "center",
duration: 2000,
});
}
}
});
},
handleSelectAddress(type, obj) {
switch (type) {
case 0:
//选择省
this.provinceObj = obj;
this.showIndex = 1;
this.cityData = obj.districts;
this.areaData = [];
this.streetsData = [];
break;
case 1:
//选择市
this.cityObj = obj;
this.showIndex = 2;
if (obj.districts) {
this.areaData = obj.districts;
this.selectAreaLevelLimit = 4
} else {
//兼容直辖市 例如 “北京市、天津市”,加上街道只有三级的情况
this.selectAreaLevelLimit = 3
uni.request({
url: 'https://apis.map.qq.com/ws/district/v1/getchildren',//腾讯地图获取下级行政区划接口,接口文档https://lbs.qq.com/service/webService/webServiceGuide/search/webServiceDistrict
data: {
key: '填写您自己在腾讯地图申请的key',
id: obj.id,//父级行政区划ID
},
success: (res) => {
if (res.data.status == 0) {
console.log(res.data);
this.areaData = res.data.result[0]
} else {
uni.showToast({
icon: "none",
title: res.data.message,
position: "center",
duration: 2000,
});
}
}
});
}
this.streetsData = [];
break;
case 2:
this.areaObj = obj;
if (this.selectAreaLevelLimit == 4) {
this.showIndex = 3;
uni.request({
url: 'https://apis.map.qq.com/ws/district/v1/getchildren',
data: {
key: '填写您自己在腾讯地图申请的key',
id: this.areaObj.id
},
success: (res) => {
if (res.data.status == 0) {
console.log(res.data);
this.streetsData = res.data.result[0]
} else {
uni.showToast({
icon: "none",
title: res.data.message,
position: "center",
duration: 2000,
});
}
}
});
}
break;
case 3:
//选择街道
this.streetObj = obj;
break;
default:
break;
}
},
},
};
</script>
css
<style lang="scss" scoped>
.page-mask {
position: fixed;
width: 100%;
height: 100vh;
z-index: 998;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.6);
}
.page-main {
height: 100vh;
position: fixed;
z-index: 999;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding: 20rpx;
border-top: 1rpx solid rgba(0, 0, 0, 0.2);
border-radius: 16rpx 16rpx 0 0;
max-height: 60%;
.main-operate {
padding: 0 10rpx 10rpx 10rpx;
display: flex;
justify-content: space-between;
.title-txt {
color: #343434;
font-size: 30rpx;
&:nth-child(2) {
color: var(--color);
}
}
}
.main-select {
display: flex;
justify-content: flex-start;
color: #343434;
font-size: 30rpx;
height: 100rpx;
line-height: 100rpx;
text {
display: inline-block;
width: 25%;
text-align: center;
overflow: hidden;
-webkit-line-clamp: 1;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
text-align: center;
}
.select {
color: var(--color);
position: relative;
&::after {
content: "";
width: 100%;
height: 6rpx;
background: var(--color);
position: absolute;
left: 0;
bottom: -8rpx;
}
}
}
.maincom {
height: 72%;
.main-list {
overflow-y: auto;
color: #343434;
font-size: 30rpx;
width: 100%;
height: 100%;
overflow: auto;
.list-box {
display: flex;
flex-direction: column;
height: 100rpx;
line-height: 100rpx;
border-bottom: 2rpx solid #dedede;
}
.list-box:last-child {
border-bottom: none;
}
.active {
color: var(--color);
}
}
}
}
</style>
二、父组件引用“一”组件
代码如下:
<UniAddressSelector v-if="showAddress" @cancel="handleCancel"
@confirm="handleConfirm" >
</UniAddressSelector>
import UniAddressSelector from './UniAddressSelector.vue'
components: {
UniAddressSelector
},
data() {
return {
showAddress: false,
address:""
}
},
methods: {
handleCancel() {
this.showAddress = false;
},
handleConfirm(areaInfoObj) {
this.showAddress = false;
//拿到完整省市区街道地址
console.log(areaInfoObj)
this.address = areaInfoObj.fullAreaText //fullAreaText: "福建省-福州市-鼓楼区-鼓东街道"
},
}
三、 pc端效果
总结
以上就是今天的内容,本文简单介绍了如何使用腾讯地图WebService API下的行政区划接口来实现客户的需求——患者选择地址精确到省市区街道。
记录:第一篇文章~~~如有问题请多多指教留言!谢谢
标签:web,WebService,color,res,areaObj,id,streetObj,data,选择器 From: https://blog.csdn.net/choinsane/article/details/143563720说明,本次项目记录是在“uniapp插件市场的省市区街道三级四级联动选择器”拿到的组件代码进行改造的,去掉了冗余的代码,改成适合自己项目使用(比较简单),也方便大家学习使用。
原组件地址:https://ext.dcloud.net.cn/plugin?id=5671