В библиотеке Naive UI взаимодействие с компонентами
через ref является мощным инструментом для управления их
состоянием и вызова методов напрямую из родительских компонентов.
Использование ref особенно актуально в случаях, когда
требуется программно управлять поведением компонентов, минуя реактивные
свойства (props) и события (events).
refДля того чтобы получить доступ к экземпляру компонента, необходимо
использовать функцию ref из Vue 3 и передать ссылку на
компонент через директиву ref в шаблоне:
<template>
<n-button ref="buttonRef" @click="handleClick">Нажми меня</n-button>
</template>
<script setup>
import { ref } from 'vue';
import { NButton } from 'naive-ui';
const buttonRef = ref(null);
function handleClick() {
console.log(buttonRef.value); // Доступ к экземпляру NButton
}
</script>
Ключевой момент: buttonRef.value содержит
экземпляр компонента, через который можно вызывать его
методы или работать с реактивными свойствами.
Многие компоненты Naive UI предоставляют публичные методы, которые
можно вызвать через ref. Например, компонент
NInput имеет метод focus() для установки
фокуса на поле ввода:
<template>
<n-input ref="inputRef" placeholder="Введите текст"></n-input>
<n-button @click="focusInput">Фокус</n-button>
</template>
<script setup>
import { ref } from 'vue';
import { NInput, NButton } from 'naive-ui';
const inputRef = ref(null);
function focusInput() {
inputRef.value?.focus(); // Программное наведение фокуса на NInput
}
</script>
Использование ?. (optional chaining) важно для
предотвращения ошибок в случае, если компонент ещё не смонтирован.
ref с
TypeScriptДля корректной работы с методами компонентов в TypeScript необходимо указать тип экземпляра:
import { ref } from 'vue';
import type { NInputInst } from 'naive-ui';
const inputRef = ref<NInputInst | null>(null);
function focusInput() {
inputRef.value?.focus();
}
Тип NInputInst содержит все публичные методы и свойства,
доступные у компонента NInput. Аналогично существуют типы
для других компонентов, например NButtonInst,
NDropdownInst, NModalInst.
ref с асинхронным рендерингомИногда доступ к компоненту через ref требуется после
того, как он полностью смонтирован. В таких случаях удобно использовать
хук onMounted:
import { ref, onMounted } from 'vue';
import { NInput } from 'naive-ui';
const inputRef = ref(null);
onMounted(() => {
inputRef.value?.focus();
});
Это гарантирует, что попытка обращения к методам компонента произойдёт только после его рендера в DOM.
Некоторые компоненты Naive UI предоставляют возможность получить
доступ не только к методам компонента, но и к его внутренним элементам
DOM. Например, NPopover можно программно открывать и
закрывать через ref:
<template>
<n-popover ref="popoverRef">
<template #trigger>
<n-button @click="togglePopover">Открыть</n-button>
</template>
Содержимое поповера
</n-popover>
</template>
<script setup>
import { ref } from 'vue';
import { NPopover, NButton } from 'naive-ui';
const popoverRef = ref(null);
function togglePopover() {
if (popoverRef.value) {
popoverRef.value.show();
}
}
</script>
Методы show() и hide() предоставляются
через интерфейс компонента NPopoverInst.
ref для коллекций компонентовПри работе с коллекцией компонентов удобно использовать массив
ref или ref с объектом, чтобы программно
управлять несколькими экземплярами:
<template>
<n-button v-for="(btn, index) in 3" :key="index" :ref="el => buttonRefs[index] = el">
Кнопка {{ index + 1 }}
</n-button>
</template>
<script setup>
import { ref } from 'vue';
import { NButton } from 'naive-ui';
const buttonRefs = [];
function clickAllButtons() {
buttonRefs.forEach(btn => btn?.click());
}
</script>
Таким образом, каждый экземпляр компонента получает отдельную ссылку, и можно управлять ими программно как единым массивом.
ref и реактивными даннымиКомбинируя ref и реактивные свойства
(reactive или ref), можно создавать мощные
динамические интерфейсы. Например, автоматическое обновление состояния
компонента при изменении внешней переменной:
<template>
<n-input ref="inputRef" v-model:value="text"></n-input>
<n-button @click="clearInput">Очистить</n-button>
</template>
<script setup>
import { ref, watch } from 'vue';
import { NInput, NButton } from 'naive-ui';
const inputRef = ref(null);
const text = ref('Привет');
function clearInput() {
text.value = '';
inputRef.value?.focus();
}
watch(text, newVal => {
console.log('Текущее значение поля:', newVal);
});
</script>
Такой подход обеспечивает прямой контроль над поведением компонентов без необходимости создавать сложные цепочки событий.
ref в Naive UIfocus(),
show(), hide() и др.).NInputInst, NButtonInst и т.д.).watch).onMounted).Использование ref в Naive UI позволяет строить сложные
интерактивные интерфейсы, сохраняя прямой и предсказуемый доступ к
поведению каждого компонента.