首页 > 其他分享 >web前端实现地址选择器精确到省市区街道(腾讯地图WebService API)

web前端实现地址选择器精确到省市区街道(腾讯地图WebService API)

时间:2024-11-06 11:44:26浏览次数:3  
标签:web WebService color res areaObj id streetObj data 选择器

目录


先看效果,这里以移动端为例

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下的行政区划接口来实现客户的需求——患者选择地址精确到省市区街道。
记录:第一篇文章~~~如有问题请多多指教留言!谢谢

说明,本次项目记录是在“uniapp插件市场的省市区街道三级四级联动选择器”拿到的组件代码进行改造的,去掉了冗余的代码,改成适合自己项目使用(比较简单),也方便大家学习使用。
原组件地址:https://ext.dcloud.net.cn/plugin?id=5671

标签:web,WebService,color,res,areaObj,id,streetObj,data,选择器
From: https://blog.csdn.net/choinsane/article/details/143563720

相关文章