在leaflet中使用vue3组件生成Marker

831 阅读1分钟

1. 问题背景

leaflet开发过程中,一般都需要在地图中打上点位标识,leaflet提供的普通Marker样式和功能都较为简单,通常无法满足业务需求。所幸leaflet还提供了一个divIcon,支持我们使用dom来生成点位图标。divIcon支持传入dom字符串或者HTMLElement

2. 官方文档用法

文档链接:leafletjs.com/reference.h…

2.1 通过dom字符串生成Marker

我们在传入字符串后还需要在css中定义样式,和绑定.myIcon的事件,一瞬间梦回jquery

const myIcon = L.divIcon({
    html: "<div class='myIcon'></div>",
    iconSize: [40, 40],
    iconAnchor: [20, 40],
});
L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);

2.2 通过HTMLElement生成Marker

这种写法如果在Marker简单的时候还挺方便的,如果需要的marker比较复杂,局限性就比较大。

const div = document.createElement("div")
div.className = "myIcon"
div.style.width = "40px"
//...
div.onclick = () => { /*...*/}

const myIcon = L.divIcon({
    html: div,
    iconSize: [40, 40],
    iconAnchor: [20, 40],
});
L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);

3. 使用vue组件生成Marker

3.1 编写vue组件

需要注意的是这个Vue组件不支持第三方组件的自动导入,如果需要用到第三方组件,需要手动引入

<!-- BaseMarker.vue -->
<template>
  <div class="myIcon" @click="onclick">
      <Avatar />
      <span>{{name}}</span>
  </div>
</template>
<script setup lang="ts">
import { Avatar } from '@arco-design/web-vue'
interface PropsType {
  name: string
}
const props = defineProps<PropsType>()
const onclick = () => { console.log("click) }
</script>
<style lang="scss" scoped>
.myIcon {
  width: 40px;
  height: 40px;
}
</style>

3.2 实例化vue组件Marker

思路其实也很简单, 其实就是实例化vue组件拿到组件还未挂载到页面的DOM,作为HTMLElement传入divIcon

import { createVNode, defineComponent, h, render } from 'vue'
import BaseMarkerVue from "BaseMarker.vue"

//实例化组件的过程
const newComponent = defineComponent({
  render() {
    return h(BaseMarkerVue, {name: "肛肠科冯主任"})
  },
})
const instance = createVNode(newComponent)
render(instance, document.createElement('div'))


const myIcon = L.divIcon({
  html: instance.el,
  iconSize: [40, 40],
  iconAnchor: [20, 40],
})
L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);