In my Vue 3 application with Vite and Pinia I have a component that imports multiple accordion subcomponents. When all accordions are mounted, I get the list with querySelectorAll.
const Byg = defineAsyncComponent(() => import('@/components/bbrObject/entityType/Byg.vue')); // Includes a lot of .accordion-button elements
const accordionList = ref([]);
onUpdated(() => {
accordionList.value = [].slice.call(document.querySelectorAll('.accordion-button')) as HTMLElement[];
console.log(accordionList.value); // <-- Empty with async import
});
This works like a charm when I import my subcomponents directly, but as soon as I update my accordion subcomponents to be imported using defineAsyncComponent, onUpdated is still triggered but the accordionList remains empty.
My issue is that I can't find a way to know when my async components are done rendering, so I can access the DOM. I have tried adding watchers, used nextTick and even tried with a setTimeout. I also tried using the promise returned by defineAsyncComponent. I can't figure out a clean way to know when all async components are done loading.
I have set up an example of the issue: https://codesandbox.io/s/mystifying-morning-frqtlv?file=/src/App.vue
The easiest way to detect when the async component is mounted is by explicitly emitting an event from it.
Then you can listen to the mounted event on your parent component
Suspense provides a resolve event. But since it is still an experimental feature, I do not recommend using it.