Vue3 中结合地图组件渲染InfoWindow

前言

前端开发使用到地图组件的时候,难免要使用到InfoWindow, 但是在使用的过程中,发现InfoWindow的内容不能直接渲染vue组件,所以就有了这篇文章。
只能通过原生的html文本进行渲染,而且事件绑定还有起的麻烦,在vue2中得将事件绑定到 window 的全局对象下,才得以调用。所以研究发现了 vue3 的一个特性,可以通过 vnode 来渲染vue组件。
话不多说,进入使用环节.

实现

  1. 先创建一个vue组件,用来渲染InfoWindow的内容。
    InfoWindow.vue

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <template>
    <div class="w-300px bg-[#303133]">
    <div class="flex flex-col p-x-20px">
    <div class="font-bold text-20px color-#009e5c" @click="handleClick('info')">
    这是InfoWindow
    </div>
    </div>
    </div>
    </template>
    <script lang="ts" setup>

    const props = defineProps({
    data: {
    type: Object,
    default: () => ({})
    }
    })

    const emit = defineEmits(['click'])

    const handleClick = (type: string) => {
    emit('click', type)
    }

    </script>
    <style lang="scss" scoped>

    </style>

    可以看到,这是一个标准的Vue3组件,包含数据data 以及 回调事件 click

  2. 在InfoWindow的content中,使用vnode来渲染vue组件。

    index.vue

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import { createVNode, render } from 'vue'
    import InfoWindow from './InfoWindow.vue'

    const showInfoWindow = () => {
    const vnode = createVNode(InfoWindow, { landData, onClick: handleClick })
    const container = document.createElement('div');
    render(vnode, container)
    mapRef.value.showInfoWindow(vnode.el, lnglat)
    }

    const handleClick = (type: string) => {
    console.log(type)
    }

    可以看到,我们使用 Vue 提供的 createVNode 方法以及 render 方法来渲染vue组件。
    createVNode 方法用来创建vnode,第一个参数传入封装的组件,第二个参数传入组件的属性, 需要注意的是 回调事件前需要加 on。
    render 方法用来渲染vnode,第一个参数传入vnode,第二个参数传入dom节点。
    可以看到,我们创建了一个div节点,用来作为InfoWindow的content,并将vnode渲染到这个div节点中。
    最后将这个div节点作为InfoWindow的content传入mapRef.value.showInfoWindow方法中。
    即可渲染成功。


Vue3 中结合地图组件渲染InfoWindow
https://stanlee12.github.io/2025/09/02/info-window/
作者
stan
发布于
2025年9月2日
许可协议