vue3 地圖(天地圖,百度地圖,騰訊地圖,高德地圖)封裝組件調用 帶地圖搜索功能common_tencent_map_ak
廢話不多說直接上組件代碼:
<template>
<!-- 地圖 -->
<div class="container w">
<div id="map" class="map radius-md" :style="{ width: width, height: height }"></div>
</div>
</template>
<script>
export default defineComponent({
props: {
modelValue: {
type: String,
default: '上海市黃浦區上海中心大廈',
},
// 是否可拖拽
draggable: {
type: Boolean,
default: true,
},
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: '350px',
},
type: {
type: String,
default: 'baidu', // 地圖類型 默認1.tianditu天地圖/2.baidu百度地圖/3.tencent騰訊地圖/4.amap高德地圖
},
},
emits: ['point'],
setup(props, context) {
// 密鑰
const common_amap_map_ak = 'xxxxxxxxxxx';
const common_amap_map_safety_ak = 'xxxxxxxxxx';
const common_baidu_map_ak = 'xxxxxxxxxx';
const common_tencent_map_ak = 'xxxxxxxxx';
const common_tianditu_map_ak = 'xxxxxxxxxxx';
const map = ref(null);
const lng = ref(121.47894);
const lat = ref(31.223);
watch(
() => props.modelValue,
(val) => {
if (!val) return;
map_event(val);
}
);
onMounted(() => {
load_map_script(); // 加載地圖資源
});
const load_map_script = () => {
// 此處在所需頁面引入資源就是,不用再public/index.html中引入
let script = document.createElement('script');
script.type = 'text/javascript';
script.className = 'loadmap'; // 給script一個類名
if (props.type === '1') {
// 天地圖
script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${common_tianditu_map_ak || 'xxx'}`;
} else if (props.type === '2') {
// 百度地圖
script.src = `https://api.map.baidu.com/getscript?v=3.0&ak=${common_baidu_map_ak || 'xxx'}`;
} else if (props.type === '3') {
// 騰訊地圖
script.src = `https://map.qq.com/api/js?v=2.exp&key=${common_tencent_map_ak || 'xxx'}&callback=init`;
} else if (props.type === '4') {
// 高德地圖
script.src = `https://webapi.amap.com/maps?v=2.0&key=${common_amap_map_ak || 'xxx'}`;
}
// 使用script.onload,待資源加載完成,再初始化地圖
if (props.type === '3') {
window.init = () => {
init();
};
load_tx_map();
} else {
script.onload = () => {
init();
};
}
let loadmap = document.getElementsByClassName('loadmap');
if (loadmap) {
// 每次append script之前判斷一下,避免重復添加script資源標簽
for (var i = 0; i < loadmap.length; i++) {
document.body.removeChild(loadmap[i]);
}
}
if (props.type === '4') {
window._AMapSecurityConfig = {
securityJsCode: common_amap_map_safety_ak || 'xxx',
};
}
document.body.appendChild(script);
};
const load_tx_map = () => {
// 此處在所需頁面引入資源就是,不用再public/index.html中引入
let script = document.createElement('script');
script.type = 'text/javascript';
script.className = 'loadmap2'; // 給script一個類名
script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${common_tencent_map_ak || 'xxx'}&libraries=service`;
let loadmap2 = document.getElementsByClassName('loadmap2');
if (loadmap2) {
// 每次append script之前判斷一下,避免重復添加script資源標簽
for (var i = 0; i < loadmap2.length; i++) {
document.body.removeChild(loadmap2[i]);
}
}
document.body.appendChild(script);
};
// 初始化地圖
const init = () => {
switch (props.type) {
case '1':
const T = window.T;
// 坐標
map.value = new T.Map('map');
let point = new T.LngLat(lng.value, lat.value);
map.value.centerAndZoom(point, 10);
// 禁止鼠標滾動縮小放大
map.value.disableScrollWheelZoom();
// 添加控件
//創建縮放平移控件對象
let control = new T.Control.Zoom();
// control.setPosition(T_ANCHOR_TOP_RIGHT);
//添加縮放平移控件
map.value.addControl(control);
map.value.clearOverLays();
let marker = new T.Marker(point);
map.value.addOverLay(marker);
if (props.draggable) {
marker.enableDragging();
marker.addEventListener('dragend', function (e) {
map.value.panTo(new T.LngLat(e.lnglat.lng, e.lnglat.lat));
lat.value = e.lnglat.lat;
lng.value = e.lnglat.lng;
context.emit('point', lng, lat);
});
}
break;
case '2':
const BMap = window.BMap;
map.value = new BMap.Map('map', {
enableMapClick: false,
});
let point2 = new BMap.Point(lng.value, lat.value);
map.value.centerAndZoom(point2, 10); // 初始化地圖,設置中心點坐標和地圖級別
// 添加控件
let navigationControl = new BMap.NavigationControl({
// 靠左上角位置
anchor: window.BMAP_ANCHOR_TOP_LEFT,
// LARGE類型
type: window.BMAP_NAVIGATION_CONTROL_LARGE,
});
map.value.addControl(navigationControl);
let marker2 = new BMap.Marker(point2);
map.value.addOverlay(marker2);
if (props.draggable) {
// 修正marker的初始化
marker2.enableDragging();
marker2.addEventListener('dragend', function (e) {
map.value.panTo(e.point);
lat.value = e.point.lat;
lng.value = e.point.lng;
context.emit('point', lng, lat);
});
// 設置標注提示信息
let cr = new BMap.CopyrightControl({ anchor: window.BMAP_ANCHOR_BOTTOM_RIGHT });
map.value.addControl(cr); //添加版權控件
let bs = map.value.getBounds(); //返回地圖可視區域
cr.addCopyright({ id: 1, content: '<div class="map-dragging-tips"><span>' + '拖動紅色圖標直接定位' + '</span></div>', bounds: bs });
}
break;
case '3':
const qq_maps = window.qq.maps;
let point3 = new qq_maps.LatLng(lat.value, lng.value);
map.value = new qq_maps.Map('map', {
center: point3,
zoom: 10,
});
let marker3 = new qq_maps.Marker({
map: map.value,
position: point3,
draggable: props.draggable,
});
qq_maps.event.addListener(marker3, 'dragend', function (e) {
lat.value = e.latLng.lat;
lng.value = e.latLng.lng;
map.value.panTo(e.latLng);
context.emit('point', lng, lat);
});
break;
case '4':
const AMap = window.AMap;
map.value = new AMap.Map('map', {
zoomEnable: true,
resizeEnable: false,
scrollWheel: false,
zoom: 10, // 初始化地圖級別
center: [lng.value, lat.value], // 初始化地圖中心點位置
});
AMap.plugin(['AMap.ToolBar'], function () {
// 在圖面添加工具條控件, 工具條控件只有縮放功能
map.value.addControl(new AMap.ToolBar());
});
// 創建標注
var marker_config = {
position: map.value.getCenter(),
// offset: new AMap.Pixel(-13, -30),
draggable: props.draggable,
};
let marker4 = new AMap.Marker(marker_config);
marker4.setMap(map);
// 標注可拖拽回調
if (props.draggable) {
marker4.on('dragend', (e) => {
map.value.panTo(e.lnglat);
lng.value = e.lnglat.lng;
lat.value = e.lnglat.lat;
context.emit('point', lng.value, lat.value);
});
}
map.value.add(marker4);
break;
}
};
const map_event = (value) => {
switch (props.type) {
case '1':
let geo = new T.Geocoder();
geo.getPoint(value, function (result) {
let point = result.getLocationPoint();
if (result.getStatus() == 0) {
lng.value = point.lng;
lat.value = point.lat;
init();
map.value.panTo(new T.LngLat(lng.value, lat.value));
context.emit('point', lng.value, lat.value);
} else {
ElMessage.info(point?.getMsg() || '您選擇地址沒有解析到結果!');
}
});
break;
case '2':
// 創建地址解析器實例
let geo2 = new window.BMap.Geocoder();
// 將地址解析結果顯示在地圖上,并調整地圖視野
geo2.getPoint(
value,
function (point) {
if (point) {
lng.value = point.lng;
lat.value = point.lat;
context.emit('point', lng.value, lat.value);
init();
} else {
ElMessage.info(point?.getMsg() || '您選擇地址沒有解析到結果!');
}
},
'全國'
);
break;
case '3':
let geo3 = new TMap.service.Geocoder();
geo3.getLocation({ address: value }).then((result) => {
let lnglat = result.result.location;
lng.value = lnglat.lng;
lat.value = lnglat.lat;
init();
context.emit('point', lng.value, lat.value);
});
break;
case '4':
AMap.plugin('AMap.Geocoder', () => {
new AMap.Geocoder().getLocation(value, (status, result) => {
if (status === 'complete' && result.geocodes.length) {
var lnglat = result.geocodes[0].location;
lng.value = lnglat.lng;
lat.value = lnglat.lat;
init();
context.emit('point', lng.value, lat.value);
} else {
ElMessage.info('您選擇地址沒有解析到結果!');
}
});
});
break;
}
};
},
});
</script>
<style lang="scss" scoped></style>
組件調用及回調:
<maps v-model="map_address" :type="common_map_type" @point="map_point"></maps>
參數:
// 地址
const map_address = ref('');
// 地圖類型
const map_type = ref('tianditu');
組件回調:
//地圖用于回調用于獲取坐標
const map_point = (lng: number, lat: number) => {
form.lng = lng;
form.lat = lat;
};
地圖效果展示:




浙公網安備 33010602011771號