Template Refs
Während das deklarative Rendering-Modell von Vue die meisten direkten DOM-Operationen für Sie abstrahiert, kann es immer noch Fälle geben, in denen wir direkten Zugriff auf die zugrunde liegenden DOM-Elemente benötigen. Um dies zu erreichen, können wir das spezielle ref
-Attribut verwenden:
template
<input ref="input">
ref
ist ein spezielles Attribut, ähnlich dem key
-Attribut, das im Kapitel v-for
besprochen wurde. Es erlaubt uns, einen direkten Verweis auf ein bestimmtes DOM-Element oder eine untergeordnete Komponenteninstanz zu erhalten, nachdem es eingebunden wurde. Dies kann nützlich sein, wenn man z.B. eine Eingabe beim Einbinden einer Komponente programmatisch fokussieren oder eine Bibliothek eines Drittanbieters für ein Element initialisieren möchte.
Zugriff auf die Refs
Um die Referenz mit der Composition API zu erhalten, müssen wir eine Referenz mit demselben Namen deklarieren:
vue
<script setup>
import { ref, onMounted } from 'vue'
// declare a ref to hold the element reference
// the name must match template ref value
const input = ref(null)
onMounted(() => {
input.value.focus()
})
</script>
<template>
<input ref="input" />
</template>
Wenn Sie nicht <script setup>
verwenden, stellen Sie sicher, dass Sie auch die Referenz von setup()
zurückgeben:
js
export default {
setup() {
const input = ref(null)
// ...
return {
input
}
}
}
Beachten Sie, dass Sie nur auf die Referenz zugreifen können, nachdem die Komponente montiert ist. Wenn Sie versuchen, auf input
in einem Template-Ausdruck zuzugreifen, wird es beim ersten Rendering null
sein. Das liegt daran, dass das Element erst nach dem ersten Rendering existiert!
Wenn Sie versuchen, die Änderungen einer Vorlagenreferenz zu überwachen, müssen Sie den Fall berücksichtigen, dass die Referenz den Wert null
hat:
js
watchEffect(() => {
if (input.value) {
input.value.focus()
} else {
// not mounted yet, or the element was unmounted (e.g. by v-if)
}
})
Siehe auch: Typing Template Refs
Refs innerhalb v-for
Requires v3.2.25 or above
Wenn ref
innerhalb von v-for
verwendet wird, sollte das entsprechende ref einen Array-Wert enthalten, der nach dem Einhängen mit den Elementen gefüllt wird:
vue
<script setup>
import { ref, onMounted } from 'vue'
const list = ref([
/* ... */
])
const itemRefs = ref([])
onMounted(() => console.log(itemRefs.value))
</script>
<template>
<ul>
<li v-for="item in list" ref="itemRefs">
{{ item }}
</li>
</ul>
</template>
Es ist zu beachten, dass das Ref-Array nicht die gleiche Reihenfolge wie das Quell-Array garantiert.
Function Refs
Anstelle eines String-Schlüssels kann das Attribut ref
auch an eine Funktion gebunden werden, die bei jeder Komponentenaktualisierung aufgerufen wird und Ihnen volle Flexibilität bei der Wahl des Speicherorts für die Elementreferenz bietet. Die Funktion erhält die Elementreferenz als erstes Argument:
template
<input :ref="(el) => { /* assign el to a property or ref */ }">
Beachten Sie, dass wir eine dynamische :ref
-Bindung verwenden, so dass wir eine Funktion anstelle einer Zeichenkette mit dem Namen ref übergeben können. Wenn das Element abgehängt wird, wird das Argument null
sein. Sie können natürlich auch eine Methode anstelle einer Inline-Funktion verwenden.
Ref zu Komponente
Dieser Abschnitt setzt Kenntnisse über Komponenten voraus. Sie können es auch überspringen und später wiederkommen.
ref
kann auch für eine untergeordnete Komponente verwendet werden. In diesem Fall wird die Referenz die einer Komponenteninstanz sein:
vue
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
const child = ref(null)
onMounted(() => {
// child.value will hold an instance of <Child />
})
</script>
<template>
<Child ref="child" />
</template>
Wenn die untergeordnete Komponente die Options-API verwendet oder kein <Skript-Setup>
verwendet, wird die referenzierte Instanz identisch mit der this
der Kindkomponente sein wird, was bedeutet, dass die Elternkomponente vollen Zugriff auf jede Eigenschaft und Methode der Kindkomponente hat. Dies macht es einfach, eng gekoppelte Implementierungsdetails zwischen der Eltern- und der Kindkomponente zu erstellen. Daher sollten Komponentenreferenzen nur verwendet werden, wenn es unbedingt notwendig ist - in den meisten Fällen sollten Sie versuchen, Eltern-/Kind-Interaktionen zuerst mit den Standardschnittstellen props und emit zu implementieren.
Eine Ausnahme hiervon ist, dass Komponenten, die <script setup>
verwenden, standardmäßig privat sind: eine Elternkomponente, die eine Kindkomponente referenziert, die <script setup>
verwendet, wird auf nichts zugreifen können, es sei denn, die Kindkomponente entscheidet sich, eine öffentliche Schnittstelle mit dem Makro defineExpose
freizugeben:
vue
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
Wenn ein Elternteil eine Instanz dieser Komponente über Template-Refs abruft, hat die abgerufene Instanz die Form { a: Zahl, b: Zahl }
(Refs werden automatisch wie bei normalen Instanzen entpackt).
Siehe auch: Typing Component Template Refs