使用谷歌地图google实现功能去选择定点位置,可以搜索位置。实现地图选择器组件:Vue + Google Maps API 实战
在现代Web应用中,地图选择器是一个常见的功能需求,尤其是在需要用户选择地理位置时。本文将详细介绍如何使用Vue.js和Google Maps API实现一个功能完善的地图选择器组件,并分享相关的技术细节和实现思路。
1. 功能概述
我们的地图选择器组件需要实现以下功能:
-
地图展示:使用Google Maps API展示地图,并允许用户通过点击或拖动标记来选择位置。
-
地址搜索:用户可以通过输入地址搜索并定位到指定位置。
-
地址与坐标绑定:将用户选择的位置信息(地址、纬度、经度)返回给父组件。
-
初始值设置:支持根据父组件传入的初始值(地址、纬度、经度)初始化地图位置。
-
重置功能:支持将地图重置为默认位置。
2. 技术栈
-
Vue.js:用于构建组件化的前端应用。
-
Google Maps API:用于地图展示、地址搜索和坐标解析。
-
Element Plus:用于UI组件(如输入框、按钮等)。
3. 实现细节
3.1 父组件:地图选择器的调用
在父组件中,我们通过一个表单项来触发地图选择器的显示,并将选择的结果绑定到表单数据中。
<el-form-item :label="$t('h.Tasklocation')" prop="address">
<el-input
v-model="form.address"
:placeholder="$t('h.PleaseEnter') + $t('h.Tasklocation')"
disabled
maxlength="255"
show-word-limit
>
<template #append>
<el-button @click="openMapSelector(form.address)">
{{ $t("h.Selectbtn") }}
</el-button>
</template>
</el-input>
</el-form-item>
-
openMapSelector
方法:用于打开地图选择器弹窗,并根据当前操作类型(如创建或编辑)初始化地图位置。
openMapSelector() {
this.mapDialogVisible = true;
if (this.$refs.mapSelector) {
if (this.approve === "Create") {
this.$refs.mapSelector.reset(); // 重置为默认值
} else {
this.$refs.mapSelector.updatePosition(
this.form.address,
parseFloat(this.form.latitude),
parseFloat(this.form.longitude)
); // 更新为当前值
}
}
}
-
handleLocationSelected
方法:用于处理地图选择器返回的数据,并更新表单数据。
handleLocationSelected({ address, latitude, longitude }) {
this.form.address = address;
this.form.latitude = latitude;
this.form.longitude = longitude;
this.mapDialogVisible = false; // 关闭地图选择器弹窗
}
3.2 子组件:地图选择器的实现
子组件是地图选择器的核心部分,负责地图的初始化、地址搜索、坐标解析等功能。
3.2.1 模板部分
<template>
<div class="map-selector">
<div class="search-container">
<div class="search-box-container">
<input
ref="searchBox"
v-model="searchText"
type="text"
class="search-box"
:placeholder="$t('h.Search') || 'Enter a location'"
/>
<i
v-if="searchText"
class="el-icon-close clear-icon"
@click="clearSearch"
></i>
</div>
<button @click="searchAddress">{{ $t("h.Search") || "Search" }}</button>
</div>
<div ref="mapContainer" class="map-container"></div>
<div class="address-container">
<p v-if="selectedAddress">
{{ $t("h.selectedAddress") || "Selected Address" }}:
{{ selectedAddress }}
</p>
<p v-if="selectedLatitude && selectedLongitude">
{{ $t("h.latitude") || "Latitude" }}: {{ selectedLatitude }},
{{ $t("h.longitude") || "Longitude" }}: {{ selectedLongitude }}
</p>
<button @click="confirmSelection" :disabled="!selectedAddress">
{{ $t("h.Confirm") || "Confirm" }}
</button>
</div>
</div>
</template>
3.2.2 脚本部分
-
initMap
方法:初始化地图,并设置标记(Marker)和点击事件。initMap() { this.map = new google.maps.Map(this.$refs.mapContainer, { center: { lat: this.selectedLatitude, lng: this.selectedLongitude }, zoom: 12, }); this.marker = new google.maps.Marker({ map: this.map, draggable: true, position: { lat: this.selectedLatitude, lng: this.selectedLongitude }, }); this.map.addListener("click", (event) => { this.marker.setPosition(event.latLng); this.geocodeLatLng(event.latLng); }); this.marker.addListener("dragend", (event) => { this.geocodeLatLng(event.latLng); }); }
-
geocodeLatLng
方法:将经纬度解析为地址。
geocodeLatLng(latLng) {
this.geocoder.geocode({ location: latLng }, (results, status) => {
if (status === "OK" && results[0]) {
this.setSelectedAddressWithLatLng(
results[0].formatted_address,
latLng
);
} else {
console.error("Geocoder failed due to: " + status);
}
});
}
-
confirmSelection
方法:将选择的位置信息返回给父组件。
confirmSelection() {
if (this.selectedAddress) {
this.$emit("location-selected", {
address: this.selectedAddress,
latitude: this.selectedLatitude,
longitude: this.selectedLongitude,
});
this.$emit("close-dialog");
}
}
4. 关键点总结
-
Google Maps API 的使用:通过
google.maps.Map
和google.maps.Marker
实现地图展示和标记功能。 -
双向数据绑定:通过
v-model
实现搜索框与数据的绑定。 -
组件通信:通过
$emit
将子组件的数据传递给父组件。 -
动态初始化:根据父组件传入的初始值动态初始化地图位置。