效果图
<template>
<div class="map-demo1">
<van-search v-model="keyword" clearable autofocus show-action placeholder="请输入位置" id="searchId" @search="onSearch">
<template #action>
<div @click="onClickButton">搜索</div>
</template>
</van-search>
<div id="container1"></div>
<div class="info-window" style="width: 80vw;" v-show="infoWindowShow" ref="infoWindowRef">
<van-cell-group>
<van-cell title="名称" :value="poi.name" />
<van-cell title="详细地址" :value="`${poi.cityname}-${poi.cityname}-${poi.name}`" />
<van-cell title="电话" :value="poi.tel" />
<van-cell title="类型" :value="poi.type" />
</van-cell-group>
</div>
</div>
</template>
<script setup lang="ts" name="MapDemo1">
// @ts-nocheck
import AMapLoader from '@amap/amap-jsapi-loader';
import { ref, onMounted,nextTick } from 'vue';
import { showNotify } from 'vant';
window._AMapSecurityConfig = {
securityJsCode: 'jscode',
}
const keyword = ref('');
const onSearch = async (val) => {
if (!val) return showNotify({ type: 'warning', message: '请先输入搜索词' });
const r = await handlePlaceSearch(val)
console.log('r', r)
}
const onClickButton = async () => {
if (!keyword.value) return showNotify({ type: 'warning', message: '请先输入搜索词' });
const r = await handlePlaceSearch(keyword.value)
console.log('r', r)
}
let AMap = null
let map = null
let marker = null
let infoWindow = null
let autoComplete = null // Autocomplete进行联想输入。
let placeSearch = null //poi
const poi = ref({}) //弹窗里面数据
const infoWindowRef = ref() //infoWindow弹窗ref
const infoWindowShow = ref(false) //控制是否弹窗显示
const initMap = async () => {
AMap = await AMapLoader.load({
key: "your key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ['AMap.AutoComplete', 'AMap.PlaceSearch'], //AutoComplete调用每天只有20次,好坑
resizeEnable: true,
Loca: {
version: "2.0.0"
}, // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).catch(err => {
showNotify('地图加载失败,请重试')
})
map = new AMap.Map('container1', {
zoom: 8, //初始化地图级别
center: [114.304569, 30.593354], //初始化地图中心点位置
mapStyle: 'amap://styles/fresh', //设置地图的显示样式
})
return map
}
//注册地图点击事件
const initEvent = () => {
map.on('click', closeInfoWindow)
}
const closeInfoWindow = e => {
infoWindowShow.value = false
}
const initInfoWindow = () => {
infoWindow = new AMap.InfoWindow({
isCustom: true, //自定义弹窗
autoMove: true,
offset: { x: 0, y: -30 },
anchor: 'bottom-center',
});
}
const initAutoComplete = () => {
autoComplete = new AMap.AutoComplete({
city: '',
citylimit: true,
input: 'searchId'
});
autoComplete.search('wuhan', (a, b) => {
if (b === 'USER_DAILY_QUERY_OVER_LIMIT') showNotify({ type: 'warning', message: '注意:搜索联想达到当日调用量最大限制' });
})
/** autoComplete鼠标点击或者回车选中某个POI信息时触发此事件 */
autoComplete.on('select', autoCompleteSelect)
}
const initPlaceSearch = () => {
placeSearch = new AMap.PlaceSearch({
pageSize: 5, // 单页显示结果条数
pageIndex: 1, // 页码
children: 0, //不展示子节点数据
map: map, // 展现结果的地图实例
autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
placeSearch.on('markerClick', handlePlaceSearchMarkerClick)
}
/**
* autoComplete鼠标点击或者回车选中某个POI信息时触发此事件
* @param e
*/
const autoCompleteSelect = e => {
console.log('e', e)
const { adcode, name } = e.poi
keyword.value = name
placeSearch.setCity(adcode) // 设置查询城市, 支持cityname(中文或中文全拼)、citycode、adcode
handlePlaceSearch(name)
}
/**
* placeSearch搜索功能,
* @param val 搜索关键词
*/
const handlePlaceSearch = val => {
return new Promise((resolve, reject) => {
placeSearch.search(val, (result, data) => {
if (result !== 'result') {
resolve(data)
}
else reject(data)
})
})
}
const handlePlaceSearchMarkerClick = (data) => {
poi.value = data.data
infoWindowShow.value = true
nextTick(() => {
infoWindow.setContent(infoWindowRef.value)
infoWindow.open(map, data.marker.getPosition())
})
}
onMounted(async () => {
await initMap()
initEvent()
initInfoWindow()
initAutoComplete()
initPlaceSearch()
})
</script>
<style scoped>
#container1 {
padding: 0px;
margin: 0px;
width: 100vw;
height: 60vh;
}
</style>