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);