'How do I get the rendered HTML of a component?
I'd like to get the innerHTML of a rendered component in Vue 3 but I don't figure out how.
I know how to do this with refs on standard HTML markup, but it doesn't work with components.
<template>
<div>
<div ref="hello"><span>Hello World</span></div>
<HelloWorld ref="helloworld"><span>Hello World</span></HelloWorld>
</div>
</template>
<script setup>
import { onMounted, ref, unref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const hello = ref();
const helloworld = ref();
onMounted(() => {
console.log(unref(hello).innerHTML); // <span>Hello World</span>
console.log(unref(helloworld).innerHTML); // undefined
});
</script>
I'm not using SSR, my current requirement is on a SPA.
I managed to do it by wrapping <HelloWorld> into a div with and id and querying it but that's a bit crappy.
Any ideas?
Thanks!
Solution 1:[1]
Add a ref="helloWorldRef" to the component then helloWorldRef.value?.$el it the same as document.querySelector(".hello-world"). You can get .children, .clientWidth, ... the same as the querySelector.
Note that the optional chaining is necessary because it can be null if not mounted yet. You'd have to implement something to be sure it is available and assigned.
E.g.
watch(
() => helloWorldRef.value?.$el,
(n) => console.log(n)
);
Solution 2:[2]
I don’t remember the exact sources, but I came across code like this:
const stopWatch = watch(helloworld, value => {
if (value) {
stopWatch();
// TODO: Start using the element
}
}, { immediate: true });
The problem is that when the current component is finished mounting, the child component may not yet have time to be mounted.
As part of a more reasonable description, you can wrap it all in a function:
function onRefReady (ref, cb) {
const stopWatch = watch(ref, value => {
if (value) {
stopWatch();
cb(value);
}
}, { immediate: true });
onScopeDispose(stopWatch);
}
And use it like this:
onRefReady(helloworld, el => {
// TODO: Start using the element
})
In short, according to the written code:
watch(ref, fn)— callsfnevery time the value ofrefchanges. Returns the function (stopWatch) thatwatchcall will terminate.{ immediate: true }— says to run the passed function immediately, in caserefalready has a non-empty value.onScopeDispose(stopWatch)— says to stop watching changes if the component is destroyed.
This code uses stopWatch to avoid memory leaks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
