基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能,同时可以进行回显
目录
1 创建key和秘钥
1.1 登录高德地图开放平台
1.2 创建应用
1.3 绑定服务创建秘钥
2 使用组件前准备
2.1 导入loader
推荐pnpm
pnpm i @amap/amap-jsapi-loader -D
2.2 在对应的组件设置秘钥
<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
securityJsCode: "安全秘钥"
};
</script>
2.3 引入css样式
<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />
3 功能实现
3.1 初始化地图
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";
let map = null;
let aMap = null;
onMounted(() => {
AMapLoader.load({
key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then(AMap => {
// 第一参数是对应的div的id
map = new AMap.Map("container", {
// 设置地图容器id
viewMode: "3D", // 是否为3D地图模式
zoom: 11, // 初始化地图级别
center: [116.397428, 39.90923] // 初始化地图中心点位置
});
aMap = AMap;
});
});
onUnmounted(() => {
map?.destroy();
});
</script>
<template>
<div id="map-box">
<div id="container" />
</div>
</template>
<style scoped>
#map-box {
width: 100%;
height: 450px;
position: relative;
}
#container {
width: 100%;
height: 100%;
}
#myPageTop {
position: absolute;
top: 5px;
right: 10px;
font-family: "Microsoft Yahei", Pinghei;
font-size: 14px;
background: none 0px 0px repeat scroll rgb(255, 255, 255);
border-width: 1px;
border-style: solid;
border-color: rgb(204, 204, 204);
border-image: initial;
margin: 10px auto;
padding: 6px;
}
#panel {
background-color: white;
max-height: 400px;
overflow-y: auto;
}
</style>
3.2 增加搜索功能
function search() {
const placeSearch = new aMap.PlaceSearch({
pageSize: 10, // 单页显示结果条数
pageIndex: 1, // 页码
map: map, // 展现结果的地图实例
panel: "panel", // 结果列表将在此容器中进行展示。
autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
//关键字查询
placeSearch.search(keyword.value);
placeSearch.on("selectChanged", function (e) {
const data = e.selected.data;
const temp = {
province: data.pname,
provinceCode: data.pcode,
city: data.cityname,
cityCode: data.citycode,
county: data.adname,
countyCode: data.adcode,
storeAddr: data.address,
storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
longitude: `${data.location.lng}`,
latitude: `${data.location.lat}`
};
// 回调父组件
emit("change", temp);
});
}
// 宏注册emit
const emit = defineEmits(["change"]);
const keyword = ref("");
<template>
<div id="map-box">
<div id="container" />
<!-- 增加的部分 -->
<div id="myPageTop">
<el-input
@keyup.enter="search"
placeholder="请输入地址"
v-model="keyword"
>
<template #prepend>
<el-button :icon="Search" @click="search" />
</template>
</el-input>
<div id="panel" />
</div>
</div>
</template>
3.3 暴露增加标记函数
let loaded = false; // 判断地图是否完成渲染
const record = []; // 记录地图未加载完成之前的添加标签记录
// 循环渲染之前记录的地址
function loadRecord() {
record.forEach(item => {
addMarker(item.longitude, item.latitude, item.content);
});
}
function addMarker(longitude: number, latitude: number, content: string) {
if (!loaded) {
record.push({ longitude, latitude, content });
return;
}
if (!longitude || !latitude) return;
const marker = new aMap.Marker({
position: [longitude, latitude],
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
anchor: "bottom-center",
offset: new aMap.Pixel(0, 0)
});
marker.setMap(map);
marker.setTitle(content);
// 设置label标签
// label默认蓝框白底左上角显示,样式className为:amap-marker-label
marker.setLabel({
direction: "bottom",
offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
});
map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
addMarker
});
4 全部代码
<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />
<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
securityJsCode: "秘钥"
};
</script>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";
let map = null;
let aMap = null;
let loaded = false;
const record = []; // 记录地图未加载完成之前的添加标签记录
onMounted(() => {
AMapLoader.load({
key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then(AMap => {
// 第一参数是对应的div的id
map = new AMap.Map("container", {
// 设置地图容器id
viewMode: "3D", // 是否为3D地图模式
zoom: 11, // 初始化地图级别
center: [116.397428, 39.90923] // 初始化地图中心点位置
});
aMap = AMap;
// 地图加载完成后会触发此回调函数
loaded = true;
loadRecord();
});
});
onUnmounted(() => {
map?.destroy();
});
// 循环渲染之前记录的地址
function loadRecord() {
record.forEach(item => {
addMarker(item.longitude, item.latitude, item.content);
});
}
function addMarker(longitude: number, latitude: number, content: string) {
if (!loaded) {
record.push({ longitude, latitude, content });
return;
}
if (!longitude || !latitude) {
console.error("缺少必要信息")
return;
}
const marker = new aMap.Marker({
position: [longitude, latitude],
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
anchor: "bottom-center",
offset: new aMap.Pixel(0, 0)
});
marker.setMap(map);
marker.setTitle(content);
// 设置label标签
// label默认蓝框白底左上角显示,样式className为:amap-marker-label
marker.setLabel({
direction: "bottom",
offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
});
map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
addMarker
});
function search() {
const placeSearch = new aMap.PlaceSearch({
pageSize: 10, // 单页显示结果条数
pageIndex: 1, // 页码
map: map, // 展现结果的地图实例
panel: "panel", // 结果列表将在此容器中进行展示。
autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
//关键字查询
placeSearch.search(keyword.value);
placeSearch.on("selectChanged", function (e) {
const data = e.selected.data;
const temp = {
province: data.pname,
provinceCode: data.pcode,
city: data.cityname,
cityCode: data.citycode,
county: data.adname,
countyCode: data.adcode,
storeAddr: data.address,
storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
longitude: `${data.location.lng}`,
latitude: `${data.location.lat}`
};
// 回调父组件
emit("change", temp);
});
}
const emit = defineEmits(["change"]);
const keyword = ref("");
</script>
<template>
<div id="map-box">
<div id="container" />
<!-- 增加的部分 -->
<div id="myPageTop">
<el-input
@keyup.enter="search"
placeholder="请输入地址"
v-model="keyword"
>
<template #prepend>
<el-button :icon="Search" @click="search" />
</template>
</el-input>
<div id="panel" />
</div>
</div>
</template>
<style scoped>
#map-box {
width: 100%;
height: 450px;
position: relative;
}
#container {
width: 100%;
height: 100%;
}
#myPageTop {
position: absolute;
top: 5px;
right: 10px;
font-family: "Microsoft Yahei", Pinghei;
font-size: 14px;
background: none 0px 0px repeat scroll rgb(255, 255, 255);
border-width: 1px;
border-style: solid;
border-color: rgb(204, 204, 204);
border-image: initial;
margin: 10px auto;
padding: 6px;
}
#panel {
background-color: white;
max-height: 400px;
overflow-y: auto;
}
</style>
5 实现效果
回显效果,会自动设置到地图中心
选点效果