Атрибут ref в Vue3
refАтрибут используется для регистрации ссылочной информации для элементов или дочерних компонентов, чтобы к DOM-элементам или экземплярам компонентов можно было напрямую обращаться в JavaScript-коде.
Базовое описание
refЭто важный способ получения DOM-элементов или экземпляров компонентов в Vue. Он позволяет напрямую управлять DOM или вызывать методы дочерних компонентов после монтирования экземпляра Vue.
- Тип: String | Function
- Назначение: Доступ к DOM-элементам или экземплярам дочерних компонентов для выполнения таких операций, как управление фокусом и вызов методов.
Базовое использование
1. Использование ref в Options API
В Options API ссылки, зарегистрированные через ref, хранятся в экземпляре компонента$refsобъект:
Пример
<div>
<input type="text" ref="inputField" />
<button @click="focusInput">Сфокусировать поле ввода</button>
</div>
</template>
<script>
export default {
methods: {
focusInput() {
// Доступ к DOM-элементам через $refs
this.$refs.inputField.focus()
}
}
}
</script>
2. Использование ref в Composition API
В Composition API рекомендуется использоватьuseTemplateRefдля получения ссылок на шаблон:
Пример
<div>
<input type="text" ref="inputField" />
<button @click="focusInput">Сфокусировать поле ввода</button>
</div>
</template>
<script setup>
import { useTemplateRef } from 'vue'
// Создайте ссылку, соответствующую имени ref в шаблоне
const inputField = useTemplateRef('inputField')
function focusInput() {
// Прямой доступ к DOM-элементу
inputField.value?.focus()
}
</script>
Сценарии использования
1. Доступ к DOM-элементам
Используя ref, можно напрямую обращаться к DOM-элементам для выполнения таких операций, как управление фокусом и получение значения:
Пример
<div>
<input type="text" ref="username" placeholder="Имя пользователя" />
<button @click="getValue">Получить значение</button>
</div>
</template>
<script>
export default {
methods: {
getValue() {
// Получить значение поля ввода
const value = this.$refs.username.value
console.log('input value:', value)
}
}
}
</script>
2. Доступ к экземплярам дочерних компонентов
Используя ref, можно получить доступ к экземпляру дочернего компонента, вызвать его методы или получить доступ к его данным:
Пример
<template>
<div>
<child-component ref="childRef"></child-component>
<button @click="callChildMethod">Вызвать метод дочернего компонента</button>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
callChildMethod() {
// Вызвать метод дочернего компонента
this.$refs.childRef.sayHello()
// Доступ к данным дочернего компонента
console.log('Данные дочернего компонента:', this.$refs.childRef.message)
}
}
}
</script>
3. Функциональный ref
ref также может принимать функцию, которая вызывается при каждом обновлении, давая вам полный контроль над тем, где хранится ссылка:
Пример
<div>
<input type="text" :ref="el => inputEl = el" />
<button @click="focusInput">Фокус</button>
</div>
</template>
<script>
export default {
data() {
return {
inputEl: null
}
},
methods: {
focusInput() {
this.inputEl?.focus()
}
}
}
</script>
Примечания
Время регистрации ref: Поскольку сам ref создаётся из результата функции render, к нему необходимо обращаться после монтирования компонента. Если
createdвы обратитесь к нему в хуке жизненного цикла,$refsон всё ещё будет пустым объектом.
Не реактивный:
$refsОн не реактивен, поэтому его не следует использовать для привязки данных в шаблонах. Используйте его только в JavaScript для операций с DOM.
Избегайте чрезмерного использования ref: управляйте DOM и дочерними компонентами по возможности через data-driven подход и обработку событий. Чрезмерное использование ref сделает код трудным для поддержки.
Пример
<script>
export default {
created() {
console.log(this.$refs.inputField) // undefined
},
mounted() {
console.log(this.$refs.inputField) // можно получить доступ
}
}
</script>
Использование с v-for
ref также можно использовать сv-forv-for, который создаёт массив, содержащий все соответствующие DOM-элементы или экземпляры компонентов:
Пример
<div>
<div v-for="(item, index) in items" :key="item.id" :ref="el => setItemRef(el, index)">
{{ item.name }}
</div>
<button @click="logRefs">Вывести все ссылки</button>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Project 1' },
{ id: 2, name: 'Project 2' },
{ id: 3, name: 'Проект 3' }
],
itemRefs: []
}
},
methods: {
setItemRef(el, index) {
if (el) {
this.itemRefs[index] = el
}
},
logRefs() {
console.log('Все ссылки:', this.itemRefs)
}
}
}
</script>
Другие расширения
Встроенные атрибуты Vue3