I have a Leaflet map. I don't use any VueJS specific wrapper libs, just plain leaflet
. I also use <script setup>
for my VueJS components.
I want to pass a Vue component to a Leaflet popup (to the bindPopup
function) as a content for that popup. It accepts ((layer: L.Layer) => L.Content) | L.Content | L.Popup
. Can I somehow render/convert a component to something that Leaflet can accept as a popup and keep it's reactivity?
_(I was able to somewhat do it by
1. adding my component to the template but hidden (v-show="false"
)
1. assigning a ref
to it (called popupElement
)
1. exposing it's root element with defineExpose
as $el
1. binding it to the marker with leafletMarker.bindPopup(popupElement.$el.innerHTML)
It renders but the reactivity is gone because innerHTML
is just static text with a content at the time of calling it, I assume)
(I found similar questions for Vue2 and for Vue3 but non of them help)
So I got it working with the help of Estus Flask. The solution a mix of both of the solutions posted in the question. I had to:
v-show="false"
)ref
to it (called for examplepopupElement
)id
to it (in case of list rendering)defineExpose
as$el
id
attributedefineExpose
asid
onMounted
or watch for the marker if it gets added in subsequently) withleafletMarker.bindPopup(popupElement.$el)
Here is the full code (The relevant parts for the question):
MapComponent:
PopupComponent:
ViewComponent