高德地图中使用 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
相关推荐
Harriet嘉14 分钟前
解决Chrome 140以上版本“此扩展程序不再受支持,因此已停用”问题 axure插件安装问题
前端·chrome
FuckPatience19 分钟前
前端Vue 后端ASP.NET Core WebApi 本地调试交互过程
前端·vue.js·asp.net
Kingsdesigner24 分钟前
从平面到“货架”:Illustrator与Substance Stager的包装设计可视化工作流
前端·平面·illustrator·设计师·substance 3d·平面设计·产品渲染
一枚前端小能手34 分钟前
🔍 那些不为人知但是好用的JS小秘密
前端·javascript
屿小夏35 分钟前
JSAR 开发环境配置与项目初始化全流程指南
前端
微辣而已37 分钟前
next.js中实现缓存
前端
Dcc1 小时前
纯 css 实现前端主题切换+自定义方案
前端·css
Zuckjet_1 小时前
第 7 篇:交互的乐趣 - 响应用户输入
前端·javascript·webgl
我总是词不达意1 小时前
vue3 + el-upload组件集成阿里云视频点播从本地上传至点播存储
前端·vue.js·阿里云·elementui
用户481178812871 小时前
求大佬解惑:高度与宽度百分比设置问题
前端