vue 使用腾讯地图API报错 Failed to execute ‘postMessage‘ on ‘Worker‘: [object Object] could not be cloned
文章目录述版本上代码vue 2.x 选项式APIvue 3.x 组合式API(setup)述最近在项目中用到腾讯地图点标记功能(MultiMarker)。发现在更新点数据的时候发生报错,怀疑是Vue的响应代理导致的。Uncaught DOMException: Failed to execute 'postMessage' on 'Worker': [object Object] could no
·
更新:
2022.6.9
用高德地图也出现类似问题,定位到了原因,看另一篇
vue 使用高德地图、腾讯地图 实例化对象报错或地图异常
述
最近在项目中用到腾讯地图点标记功能(MultiMarker)。
发现在更新点数据的时候发生报错,怀疑是Vue的响应代理导致的。
Uncaught DOMException: Failed to execute 'postMessage' on 'Worker': [object Object] could not be cloned.
已发现受影响的方法
- setGeometries()
- updateGeometries()
- add()
不知道是不是我写法的问题?
网上没找到解决办法,摸索出了一个方案,支持vue 2.x和vue 3.x,见下文。
版本
腾讯位置服务:JavaScript API GL
Vue:2.x, 3.x
上代码
vue 2.x 选项式API
会报错的写法
<script>
export default {
data () {
return {
TMap: null, // 腾讯地图工具类实例
map: null, // 地图实例
marker: null, // 标注点图层实例
}
},
async mounted() {
await this.initMap()
this.initMarker()
setTimeout(() => {
this.updateMarker()
}, 3000)
},
methods: {
initMap () {
// 创建工具类和地图实例,存入变量中
...
},
initMarker () {
// 创建标注点图层存入变量
// 构建实例代码相同,以下不再重复
const { TMap, map } = this
this.marker = new TMap.MultiMarker({
map,
styles: {
start: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png',
})
},
geometries: [
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.98481500648338, 116.30571126937866),
}
],
})
},
updateMarker () {
// 在这里用就会报错(已经不是最初的TA了)
this.marker.updateGeometries([
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.982348784165886, 116.3111400604248),
}
])
}
}
}
</script>
改一下 updateGeometries() 的位置,就能正常使用
methods: {
initMarker () {
// 创建标注点图层存入变量
const { TMap, map } = this
const marker = new TMap.MultiMarker({...
})
this.marker = marker
// 在这里可以成功更新标注点
marker.updateGeometries([
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.982348784165886, 116.3111400604248),
}
])
}
}
因此怀疑是受Vue响应代理影响,把实例变量放到外面试试,果然成功了。
正常使用的写法
<script>
// * 存放实例的变量放到外面来
let TMap, map, marker
export default {
async mounted() {
await this.initMap()
this.initMarker()
setTimeout(() => {
this.updateMarker()
}, 3000)
},
methods: {
initMap () {
// 创建工具类和地图实例,存入变量
...
},
initMarker () {
// 创建标注点图层,存入变量
marker = new TMap.MultiMarker({...
})
},
updateMarker () {
// 现在可以成功更新标注点
marker.updateGeometries([
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.982348784165886, 116.3111400604248),
}
])
}
}
}
</script>
vue 3.x 组合式API(setup)
与选项式相同,受响应代理影响的实例无法使用某些方法。
会报错的写法
<script setup>
import { ref, onMounted } from 'vue'
let TMap, map
const marker = ref(null)
onMounted(async () => {
await initMap()
initMarker()
setTimeout(() => {
updateMarker()
}, 3000)
})
const initMarker = () {
// 创建标注点图层,存入变量
marker.value = new TMap.MultiMarker({...
})
}
// 其余代码相同
const updateMarker = () => {
// 这样写会导致报错
marker.value.updateGeometries([
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.982348784165886, 116.3111400604248),
}
])
}
</script>
正常使用的写法
<script setup>
import { onMounted } from 'vue'
// * 存放实例的变量放到外面来
let TMap, map, marker
const initMap = async () => {
// 创建工具类和地图实例,存入变量中
...
}
const initMarker = () {
// 创建标注点图层,存入变量
marker = new TMap.MultiMarker({...
})
}
const updateMarker = () => {
// 可以成功更新标注点
marker.updateGeometries([
{
id: 'start',
styleId: 'start',
position: new TMap.LatLng(39.982348784165886, 116.3111400604248),
}
])
}
</script>
完成。
更多推荐
已为社区贡献1条内容
所有评论(0)