vue3 + 腾讯地图API + 拖拽定位
vue3 + 腾讯地图API + 拖拽定位
vue3 + 腾讯地图API + 拖拽定位
作为一个前端的新手,没有经过系统学习前端,所有都是一点点找资料实践后摸索出来。文中有写两个暂时无法解决的Bug,希望有人可以不吝赐教。如果有错误,欢迎各位指正。
前提:当前我用的是vue3,在组件中都使用了setup语法糖以及使用typescript,因此在每个组件都用了
<script lang="ts" setup>
首先,在腾讯官网上申请API。
https://lbs.qq.com/dev/console/quota/mine
并且在index.html加入引入JS文件接入腾讯地图API的语句,语句中需要使用KEY。
<script src="https://map.qq.com/api/gljs?v=2.exp&key="在腾讯官网申请的KEY"></script>
现在新建一个子组件,在里面写入(注意这里ID可以自己修改,但是下面js部分需要与此处相同)
<template>
<div id="QQMap" />
</template>
<script lang="ts" setup>
</script>
<style>
</style>
现在开始写script中地图新建部分:
导入需要的库后,首先我先保存了自己的key方便后续使用。
之后的TMap是需要的,第一次按照官网写,一直找不到这个TMap,我在网上找很多资料中最终发现这句话,加入后后面就能跑了,似乎是因为外部引入script后都在window下了。
最后新建一个变量存入拖动后经纬度以及后续初始化的地图和图层。
import { onMounted, reactive, watch } from "vue";
import $ from "jquery";
const key = "";
const TMap = (window as any).TMap;
const dataMap = reactive({
map: "" as any,
markerLayer: "" as any,
latitude: 0 as number, //纬度
lngitude: 0 as number, //经度
});
在这里写入几个函数。
第一个是获取非精确地址的,通过IP地址获取当前精确到市级位置,详细介绍看官网链接:https://lbs.qq.com/service/webService/webServiceGuide/webServiceIp
// 异步获得位置
// 通过终端设备IP地址获取其当前所在地理位置,精确到市级
// 常用于初始化用户城市等非精确定位场景。
const getNowLngAndLat = $.ajax({
type: 'get',
url: 'https://apis.map.qq.com/ws/location/v1/ip',
data: {
key: key,
output: 'jsonp',
},
dataType: 'jsonp',
success: function (res) {
// console.log(res)
dataMap.latitude = res.result.location.lat;
dataMap.lngitude = res.result.location.lng;
},
fail: function () {
}
})
第二个是初始化地图,这里获取的ID需要与之前写的ID相同。
(小疑惑:在子组件中没问题,但是移到父组件初始化就会报错:
Cannot read properties of null (reading ‘id’),按照网上说法加入window.onlaod仍然不行,至今未解决)
const init = () => {
let center = new TMap.LatLng(dataMap.latitude, dataMap.lngitude);
dataMap.map = new TMap.Map(document.getElementById("QQMap"), {
center: center, //设置地图中心点坐标
zoom: 17.2, //设置地图缩放级别
});
};
第三个就是删除无用信息了,腾讯地图有他的logo和罗盘等,我不想要,因此写入函数去除。中间如果修改了ID也需要修改
// 去除无用信息
const deleteSomeInfo = () => {
// 腾讯地图去除logo
var logo = document.querySelector(
"#QQMap > div > div:nth-child(2) > div:nth-child(1) > div:nth-child(2)"
) as Element;
logo.setAttribute("style", "display: none;");
// 腾讯地图去除logo文字
var logoText = document.getElementsByClassName("logo-text");
logoText[0].setAttribute("style", "display: none;");
// 腾讯地图去除罗盘
var logoCompass = document.getElementsByClassName("rotate-circle");
logoCompass[0].setAttribute("style", "display: none;");
// 获取缩放控件实例
let control = dataMap.map.getControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM);
// 设置控件在右下角
control.setPosition(TMap.constants.CONTROL_POSITION.BOTTOM_RIGHT);
// 缩放控件显示缩放级别
control.setNumVisible(true);
};
最后一个添加图层我们先暂时不说,先说我们调用时顺序,这里首先调用获取当前粗略位置函数,获取后进入初始化,初始化使用当前经纬度,之后删除信息,最后就是我们加入图层函数。
onMounted(() => {
$.when(getNowLngAndLat).done(function () {
init();
deleteSomeInfo();
addMarkerLayer();
});
});
为什么这里的加入图层最后讲呢,因为Bug就是这里出现的,而且暂时不知如何解决
加入图层本来是正常,首先加入点,并且获取地图中心位置,之后添加图层,并且监控地图是否平移,一旦移动,修改经纬度并且更新标记点。之后本想使用官网给的updateGeometries函数,但是一直报错,如下:
Uncaught DOMException: Failed to execute ‘postMessage’ on ‘Worker’: # could not be cloned.
新手找了很多资料还是没找到解决办法,只能曲线救国,先删除再加入,但是这样就会导致标记点一直闪烁。算是最难受的一个bug了。
const addMarkerLayer = () => {
// 加入标记点
var markerGeo = {
id: "center",
position: dataMap.map.getCenter(),
};
// 创建一个位于地图中心点的marker
dataMap.markerLayer = new TMap.MultiMarker({
map: dataMap.map, //指定地图容器
geometries: [markerGeo], //点标记数据数组
});
//监听地图平移,panstart开始平移,panend平移结束
dataMap.map.on("pan", function () {
markerGeo.position = dataMap.map.getCenter(); //获取地图中心点
dataMap.latitude = markerGeo.position.lat;
dataMap.lngitude = markerGeo.position.lng;
// dataMap.markerLayer.updateGeometries([markerGeo]); // 报错,只好先删后加
dataMap.markerLayer.setMap(null); // 或者dataMap.markerLayer.destroy();
dataMap.markerLayer = new TMap.MultiMarker({
map: dataMap.map, //指定地图容器
//点标记数据数组
geometries: [markerGeo],
});
});
};
最后加上两个没有用到的函数吧。
第一个是动态加载的函数,用于尝试的,后面也没有使用他:
// 动态加载script,如果index.html去除script,在这里需要动态加载
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://map.qq.com/api/gljs?v=1.exp&key=" + key;
document.body.appendChild(script);
}
第二是飞到某个地方的函数
function easeTo(lng: number, lat: number) {
// console.log([lat,lng])
var center = new TMap.LatLng(lat, lng);
dataMap.latitude = lat;
dataMap.lngitude = lng;
dataMap.map.easeTo({ center: center }, { duration: 2000 });//平滑缩放,旋转到指定级别
}
这样就可以在父组件调用该组件即可出现腾讯地图了。效果如下:
第一次写这么长博客,有错误或者知道bug欢迎各位大佬斧正。
更多推荐
所有评论(0)