Как получить ref компонента сразу после его отрисовки при условном рендеринге во Vue
Что проверяют
Понимаете ли вы, что при v-if дочерний компонент появляется не в момент смены условия, а после ближайшего обновления DOM, и что mounted родителя тут ни при чём. Следом обычно спрашивают, почему ref компонента на <script setup> не даёт доступа к его методам.
Как отвечать
Отвечайте на примере Vue 3 и Composition API, Vue 2 уже не поддерживается.
nextTickпосле смены условия: если флаг переключаете вы сами, тоshow.value = true; await nextTick();, и после этогоchild.valueзаполнен. Подходит, когда место переключения известно;watchна сам ref: шаблонный ref становится экземпляром при монтировании иnullпри размонтировании, поэтомуwatch(child, (inst) => { if (inst) inst.open(); })срабатывает ровно тогда, когда компонент появился, кто бы ни поменял условие;- функциональный ref:
:ref="(el) => { if (el) onReady(el) }"вызывается с экземпляром при монтировании и сnullпри удалении. Удобно, когда элементов много; useTemplateRef('child'): с Vue 3.5 рекомендуемый способ объявить ref, имя переменной больше не обязано совпадать с атрибутом;- событие из дочернего: ребёнок в
onMountedвызываетemit('ready'), родитель слушает@ready. Самый явный контракт, если нужна инициализация, а не просто ссылка.
Если элемент нужен всегда, а скрывается лишь визуально, v-show вместо v-if оставляет его в DOM, и ref не пустеет. Для компонента на <script setup> помните про defineExpose: без него через ref видны только $el и служебные поля, а ваши методы закрыты.
Где спотыкаются
Читают ref в onMounted родителя. Если условие изначально ложно, там null, а при последующем включении хук родителя уже не вызовется.
Обращаются к ref сразу после присваивания флага без await nextTick(). DOM обновляется асинхронно, в этот момент компонента ещё нет.
Ловят появление ребёнка в onUpdated. Хук срабатывает на любое изменение родителя, код выполняется десятки раз и обрастает проверками, хотя watch на ref решает задачу точно.