Vue3管理后臺(tái)項(xiàng)目使用高德地圖選點(diǎn)的實(shí)現(xiàn)
前言
最近在做的管理后臺(tái)項(xiàng)目中有一個(gè)業(yè)務(wù)場(chǎng)景是添加門(mén)店的地址和經(jīng)緯度,地址可以輸入,但經(jīng)緯度這樣處理卻不合適,最好是讓用戶(hù)在地圖上搜索或者直接點(diǎn)擊獲取點(diǎn)的經(jīng)緯度等詳細(xì)信息。因?yàn)槲覀兊腶pp中使用了高德地圖,所以管理后臺(tái)我也選用高德地圖來(lái)實(shí)現(xiàn)上面的業(yè)務(wù)需求,下面來(lái)看一下具體的使用流程吧。
獲取地圖Key
- 登錄高德開(kāi)放平臺(tái)
- 創(chuàng)建應(yīng)用,添加Key,選擇Web端(JS API),生成Key和安全密鑰
引入地圖 JSAPI
項(xiàng)目中使用了官方推薦的 JSAPI Loader 來(lái)加載地圖
- 安裝官方 npm 包 @amap/amap-jsapi-loader
- 配置安全密鑰(不安全的方式),其它配置方式在這里
<script setup>
import AMapLoader from '@amap/amap-jsapi-loader';
window._AMapSecurityConfig = {
securityJsCode: '你申請(qǐng)的安全密鑰',
};
</script>初始化地圖
- 創(chuàng)建一個(gè)id為mapContainer的div元素
- 調(diào)用initMap方法初始化相關(guān)地圖插件
<script setup>
const map = shallowRef(null);
let AMapObj;
function initMap() {
AMapLoader.load({
key: '你申請(qǐng)的Key',
version: '2.0',
}).then(AMap => {
AMapObj = AMap;
map.value = new AMap.Map('mapContainer');
})
}
</script>地圖選點(diǎn)
項(xiàng)目中提供搜索選點(diǎn)和直接點(diǎn)擊地圖選點(diǎn)兩種方法
- 搜索選點(diǎn):使用 element-plus 的 autocomplete 組件結(jié)合地圖搜索服務(wù)實(shí)現(xiàn)下拉選擇地點(diǎn)
- 點(diǎn)擊選點(diǎn):借助地圖點(diǎn)擊事件獲取地點(diǎn)的經(jīng)緯度信息,然后使用地圖逆地理編碼api解析出地址信息 選擇地點(diǎn)之后同步繪制 marker 標(biāo)記,同時(shí)將 marker 移動(dòng)到地圖中心點(diǎn)并設(shè)置縮放比例
組件化使用
為了方便一整套邏輯的復(fù)用,我將以上流程全部封裝到一個(gè)組件中,通過(guò) v-model 綁定所選地點(diǎn)的詳細(xì)信息,方便選擇地點(diǎn)之后將信息同步到父組件。
下面貼出組件全部的代碼
<template>
<div class="map-wrapper">
<div id="mapcontainer"></div>
<div class="search-box">
<el-autocomplete
v-model="keyword"
:fetch-suggestions="handleSearch"
:trigger-on-focus="false"
clearable
placeholder="輸入城市+關(guān)鍵字搜索"
@select="handleSelect"
style="width: 300px"
/>
<el-input
v-model="location.longitude"
placeholder="點(diǎn)擊地圖選擇經(jīng)度"
maxlength="15"
readonly
style="width: 150px; margin: 0 5px"
></el-input>
<el-input
v-model="location.latitude"
placeholder="點(diǎn)擊地圖選擇緯度"
maxlength="15"
readonly
style="width: 150px"
></el-input>
</div>
</div>
</template>
<script setup>
import AMapLoader from '@amap/amap-jsapi-loader';
window._AMapSecurityConfig = {
securityJsCode: '你申請(qǐng)的安全密鑰',
};
const props = defineProps({
modelValue: {
type: Object,
default() {
return {};
},
},
});
const emit = defineEmits(['update:modelValue']);
const map = shallowRef(null);
// 地點(diǎn)
const location = computed({
get() {
return props.modelValue;
},
set(val) {
emit('update:modelValue', val);
},
});
watch(location, (val) => {
if (val.longitude && val.latitude) {
drawMarker();
}
}
);
const keyword = ref('');
let placeSearch, AMapObj, marker, geocoder;
function initMap() {
AMapLoader.load({
key: '', // 申請(qǐng)好的Web端Key,首次調(diào)用 load 時(shí)必填
version: '2.0'
}).then(AMap => {
AMapObj = AMap;
map.value = new AMap.Map('mapcontainer');
// 添加點(diǎn)擊事件
map.value.on('click', onMapClick);
if (location.value.longitude) {
drawMarker();
}
AMap.plugin(
['AMap.ToolBar','AMap.Scale','AMap.Geolocation','AMap.PlaceSearch', 'AMap.Geocoder'],
() => {
// 縮放條
const toolbar = new AMap.ToolBar();
// 比例尺
const scale = new AMap.Scale();
// 定位
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默認(rèn):true
timeout: 10000, //超過(guò)10秒后停止定位,默認(rèn):5s
position: 'RT', //定位按鈕的??课恢?
buttonOffset: new AMap.Pixel(10, 20), //定位按鈕與設(shè)置的??课恢玫钠屏?,默認(rèn):Pixel(10, 20)
zoomToAccuracy: true, //定位成功后是否自動(dòng)調(diào)整地圖視野到定位點(diǎn)
});
geocoder = new AMap.Geocoder({
city: '全國(guó)',
});
map.value.addControl(geolocation);
map.value.addControl(toolbar);
map.value.addControl(scale);
placeSearch = new AMap.PlaceSearch({
map: map.value,
city: '',
pageSize: 30, // 單頁(yè)顯示結(jié)果條數(shù)
pageIndex: 1, // 頁(yè)碼
citylimit: false, // 是否強(qiáng)制限制在設(shè)置的城市內(nèi)搜索
autoFitView: true,
});
}
);
})
}
onMounted(() => {
initMap();
});
// 搜索地圖
function handleSearch(queryString, cb) {
placeSearch.search(queryString, (status, result) => {
if (result && typeof result === 'object' && result.poiList) {
const list = result.poiList.pois;
list.forEach(item => {
item.value = item.name;
item.label = item.name;
});
cb(list);
} else {cb([])}
});
}
// 點(diǎn)擊地圖
function onMapClick(e) {
const { lng, lat } = e.lnglat;
// 逆地理編碼
geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.info === 'OK') {
const { addressComponent, formattedAddress } = result.regeocode;
let { city, province, district } = addressComponent;
if (!city) {
// 直轄市
city = province;
}
location.value = {
longitude: lng,
latitude: lat,
address: formattedAddress,
zone: [province, city, district],
};
}
});
}
// 點(diǎn)擊搜索項(xiàng)
function handleSelect(item) {
const { pname, cityname, adname, address, name } = item;
const { lng, lat } = item.location;
location.value = {
longitude: lng,
latitude: lat,
address,
zone: [pname, cityname, adname],
name,
};
map.value.setZoomAndCenter(16, [lng, lat]);
}
// 繪制地點(diǎn)marker
function drawMarker(val) {
const { longitude, latitude } = location.value || val;
if (marker) {
marker.setMap(null);
}
marker = new AMapObj.Marker({
position: new AMapObj.LngLat(longitude, latitude),
anchor: 'bottom-center',
});
map.value.add(marker);
map.value.setZoomAndCenter(16, [longitude, latitude]);
}
</script>
<style lang="scss" scoped>
.map-wrapper {
position: relative;
width: 100%;
height: 400px;
#mapcontainer {
width: 100%;
height: 100%;
}
.search-box {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
display: flex;
align-items: center;
}
}
</style>拓展
如果系統(tǒng)適配了暗黑模式,可以通過(guò)監(jiān)聽(tīng)當(dāng)前暗黑模式狀態(tài),來(lái)動(dòng)態(tài)切換地圖淺色主題和深色主題,從而實(shí)現(xiàn)地圖暗黑模式的適配,這就留給大家自行探索了。
到此這篇關(guān)于Vue3管理后臺(tái)項(xiàng)目使用高德地圖選點(diǎn)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3 高德地圖選點(diǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問(wèn)題
今天小編就為大家分享一篇解決Vue中引入swiper,在數(shù)據(jù)渲染的時(shí)候,發(fā)生不滑動(dòng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue項(xiàng)目使用$router.go(-1)返回時(shí)刷新原來(lái)的界面操作
這篇文章主要介紹了vue項(xiàng)目使用$router.go(-1)返回時(shí)刷新原來(lái)的界面操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
Vue跳轉(zhuǎn)頁(yè)面的幾種常用方法總結(jié)
在Vue.js中,頁(yè)面跳轉(zhuǎn)是構(gòu)建單頁(yè)面應(yīng)用(SPA)的基本操作之一,本文將介紹Vue中實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)的幾種方法,并通過(guò)實(shí)例代碼幫助理解每種方法的用法,需要的朋友可以參考下2024-09-09
vue的列表交錯(cuò)過(guò)渡實(shí)現(xiàn)代碼示例
這篇文章主要介紹了vue的列表交錯(cuò)過(guò)渡實(shí)現(xiàn)代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

