高德地图中使用 Vue 组件自定义Marker标点或InfoWindow信息窗体

原理

在高德地图中使用Vue组件进行自定义Marker、InfoWindow

new AMap.Marker(opts: MarkerOptions)

new AMap.InfoWindow(opts: InfoOptions)

属性 描述
opts.content 类型:`(string HTMLElement)`

查看文档可以知道 content 的属性可以接收HTMLElement元素,我们可以通过创建一个HTMLElement元素,然后将vue组件挂载到这个元素上。

代码示例

  • vue3
  • ts
  • amap-jsapi-loader

CreateHTML.ts 创建元素

使用createApp创建vue实例,传入组件

返回元素、vue实例(这个实例返回很重要)

ts 复制代码
/**
 * 创建vue元素
 */
export const createHTML = (comp: Component, props?: Record<string, unknown>) => {
  const element = document.createElement('div')
  const app = createApp(comp, props)
  app.mount(element)

  return {
    element, app
  }
}

vue组件

vue 复制代码
<script setup lang="ts">
defineOptions({
  name: 'Marker'
})
const props = defineProps<{
  name: string
}>()
</script>

<template>
  <h2>{{ props.name }}</h2>
</template>

<style scoped>
h2 {
  background: #115c5c;
  padding: 5px 10px;
  border-radius: 5px;
}
</style>

创建自定义Marker

拿Marker做个示例 InfoWindow同理

ts 复制代码
// 创建vue元素
const {app,element} = createHTML(MyComp,{
    name: '这是一个自定义的Marker',
})

// 创建覆盖物
const marker = new AMap.Marker({
    content: element,
    // ...otherConf
})

// 添加到地图
map.add(marker)

这样就创建了一个自定义Marker。我们也可以在vue调试工具中看到这个App实例。

这样本来是没什么问题的,但是......

当我们将marker销毁的时候App实例仍然存在,所以当我们对marker(InfoWindow)进行移除的同时,需要把App的实例也进行销毁。

ts 复制代码
// 移除标点
marker.remove()
// 销毁app
app.unmount()

扩展

使用pinia 或者组件库

由于我们是创建了一个新的vue实例,如果我们要在组件内使用pinia、或者其他组件库、插件,我们需要再写一遍配置

修改创建HTML方法

ts 复制代码
/**
 * 创建vue元素
 */
export const createHTML = (comp: Component, props?: Record<string, unknown>) => {
  const element = document.createElement('div')
  const app = createApp(comp, props)

  /** 引入pinia 或者其他配置**/
  
  // 引入相同的pinia 可以与其他实例通过pinia进行通信
  app.use(pinia)
  
  /** 引入pinia **/
  

  app.mount(element)

  return {
    element, app
  }
}

新的问题

问题1

由于组件动态生成,生成后异步获取数据,元素依旧可能变化,最后生成的元素高度、宽度可能不定,导致Marker、InfoWindow生成的位置不正确。

不完全解决办法

  1. 固定元素宽高
  2. 不在组件内异步获取数据,在组件外获取数据后再传入组件,生成Marker
相关推荐
vivo互联网技术27 分钟前
下一代图片格式 AVIF 在 vivo 社区的落地实践
前端·性能优化·图片压缩·avif
咸鱼翻身更入味30 分钟前
Vue创建一个简单的Agent聊天
前端
布局呆星36 分钟前
Vue Router 核心知识点梳理
前端·javascript·vue.js
得物技术39 分钟前
基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术
前端·人工智能·后端
不会写DN44 分钟前
如何通过 Python 实现招聘平台自动投递
开发语言·前端·python
miaowmiaow1 小时前
一行命令把 PSD 还原成 HTML / React / Vue:psd2code 实战干货
前端·ai编程
张元清1 小时前
React 中的语音与摄像头输入:语音识别、媒体设备与权限
前端·javascript·面试
用户841794814561 小时前
vxe-table 实现撤销与重做:单元格编辑后支持 Ctrl+Z 回退
前端
石小石Orz1 小时前
OpenAI官方:harness-engineering(工程技术:在智能体优先的世界中利用 Codex)
前端·后端