You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/api/composition-api-helpers.md
+66-2Lines changed: 66 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -4,18 +4,45 @@
4
4
5
5
Returns the `attrs` object from the [Setup Context](/api/composition-api-setup#setup-context), which includes the [fallthrough attributes](/guide/components/attrs#fallthrough-attributes) of the current component. This is intended to be used in `<script setup>` where the setup context object is not available.
`useModel()`canbeusedinnon-SFCcomponents, e.g. whenusingraw`setup()`function. It expects the `props` object as the first argument, and the model name as the second argument. The optional third argument can be used to declare custom getter and setter for the resulting model ref. Note that unlike `defineModel()`, you are responsible for declaring the props and emits yourself.
18
30
31
+
-**Type**
32
+
33
+
```ts
34
+
function useModel(
35
+
props: Record<string, any>,
36
+
key: string,
37
+
options?: DefineModelOptions
38
+
)
39
+
40
+
type DefineModelOptions<T = any> = {
41
+
get?: (v: T) => any
42
+
set?: (v: T) => any
43
+
}
44
+
```
45
+
19
46
-**Example**
20
47
21
48
```js
@@ -31,9 +58,46 @@ This is the underlying helper that powers [`defineModel()`](/api/sfc-script-setu
Copy file name to clipboardExpand all lines: src/guide/essentials/template-refs.md
+78-2Lines changed: 78 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,32 @@ While Vue's declarative rendering model abstracts away most of the direct DOM op
12
12
13
13
<divclass="composition-api">
14
14
15
-
To obtain the reference with Composition API, we need to declare a ref with a name that matches the template ref attribute's value:
15
+
To obtain the reference with Composition API, we can use the [`useTemplateRef()`](/api/composition-api-helpers#usetemplateref) <sup class="vt-badge" data-text=
16
+
"3.5+" /> helper:
17
+
18
+
```vue
19
+
<script setup>
20
+
import { useTemplateRef, onMounted } from 'vue'
21
+
22
+
// the first argument must match the ref value in the template
23
+
const input = useTemplateRef('my-input')
24
+
25
+
onMounted(() => {
26
+
input.value.focus()
27
+
})
28
+
</script>
29
+
30
+
<template>
31
+
<input ref="my-input" />
32
+
</template>
33
+
```
34
+
35
+
When using TypeScript, Vue's IDE support and `vue-tsc` will automatically infer the type of `inputRef.value` based on what element or component the matching `ref` attribute is used on.
36
+
37
+
<details>
38
+
<summary>Usage before 3.5</summary>
39
+
40
+
In versions before 3.5 where `useTemplateRef()` was not introduced, we need to declare a ref with a name that matches the template ref attribute's value:
16
41
17
42
```vue
18
43
<script setup>
@@ -46,6 +71,8 @@ export default {
46
71
}
47
72
```
48
73
74
+
</details>
75
+
49
76
</div>
50
77
<divclass="options-api">
51
78
@@ -95,6 +122,33 @@ See also: [Typing Template Refs](/guide/typescript/composition-api#typing-templa
95
122
96
123
When `ref` is used inside `v-for`, the corresponding ref should contain an Array value, which will be populated with the elements after mount:
97
124
125
+
```vue
126
+
<script setup>
127
+
import { ref, useTemplateRef, onMounted } from 'vue'
128
+
129
+
const list = ref([
130
+
/* ... */
131
+
])
132
+
133
+
const itemRefs = useTemplateRef('items')
134
+
135
+
onMounted(() => console.log(itemRefs.value))
136
+
</script>
137
+
138
+
<template>
139
+
<ul>
140
+
<li v-for="item in list" ref="items">
141
+
{{ item }}
142
+
</li>
143
+
</ul>
144
+
</template>
145
+
```
146
+
147
+
[Try it in the Playground](https://play.vuejs.org/#eNp9UsluwjAQ/ZWRLwQpDepyQoDUIg6t1EWUW91DFAZq6tiWF4oU5d87dtgqVRyyzLw3b+aN3bB7Y4ptQDZkI1dZYTw49MFMuBK10dZDAxZXOQSHC6yNLD3OY6zVsw7K4xJaWFldQ49UelxxVWnlPEhBr3GszT6uc7jJ4fazf4KFx5p0HFH+Kme9CLle4h6bZFkfxhNouAIoJVqfHQSKbSkDFnVpMhEpovC481NNVcr3SaWlZzTovJErCqgydaMIYBRk+tKfFLC9Wmk75iyqg1DJBWfRxT7pONvTAZom2YC23QsMpOg0B0l0NDh2YjnzjpyvxLrYOK1o3ckLZ5WujSBHr8YL2gxnw85lxEop9c9TynkbMD/kqy+svv/Jb9wu5jh7s+jQbpGzI+ZLu0byEuHZ+wvt6Ays9TJIYl8A5+i0DHHGjvYQ1JLGPuOlaR/TpRFqvXCzHR2BO5iKg0Zmm/ic0W2ZXrB+Gve2uEt1dJKs/QXbwePE)
[Try it in the Playground](https://play.vuejs.org/#eNpFjs1qwzAQhF9l0CU2uDZtb8UOlJ576bXqwaQyCGRJyCsTEHr3rGwnOehnd2e+nSQ+vW/XqMSH6JdL0J6wKIr+LK2evQuEhKCmBs5+u2hJ/SNjCm7GiV0naaW9OLsQjOZrKNrq97XBW4P3v/o51qTmHzUtd8k+e0CrqsZwRpIWGI0KVN0N7TqaqNp59JUuEt2SutKXY5elmimZT9/t2Tk1F+z0ZiTFFdBHs738Mxrry+TCIEWhQ9sttRQl0tEsK6U4HEBKW3LkfDA6o3dst3H77rFM5BtTfm/P)
174
+
</details>
121
175
122
176
</div>
123
177
<divclass="options-api">
@@ -173,6 +227,26 @@ Note we are using a dynamic `:ref` binding so we can pass it a function instead
173
227
174
228
<divclass="composition-api">
175
229
230
+
```vue
231
+
<script setup>
232
+
import { useTemplateRef, onMounted } from 'vue'
233
+
import Child from './Child.vue'
234
+
235
+
const childRef = useTemplateRef('child')
236
+
237
+
onMounted(() => {
238
+
// childRef.value will hold an instance of <Child />
Copy file name to clipboardExpand all lines: src/guide/typescript/composition-api.md
+32-25Lines changed: 32 additions & 25 deletions
Original file line number
Diff line number
Diff line change
@@ -371,6 +371,17 @@ const foo = inject('foo') as string
371
371
372
372
## Typing Template Refs {#typing-template-refs}
373
373
374
+
With Vue 3.5 and `@vue/language-tools` 2.1 (powering both the IDE language service and `vue-tsc`), the type of refs created by `useTemplateRef()` in SFCs can be **automatically inferred** for static refs based on what element the matching `ref` attribute is used on.
375
+
376
+
In cases where auto-inference is not possible, you can still cast the template ref to an explicit type via the generic argument:
377
+
378
+
```ts
379
+
const el =useTemplateRef<HTMLInputElement>(null)
380
+
```
381
+
382
+
<details>
383
+
<summary>Usage before 3.5</summary>
384
+
374
385
Template refs should be created with an explicit generic type argument and an initial value of `null`:
375
386
376
387
```vue
@@ -389,50 +400,45 @@ onMounted(() => {
389
400
</template>
390
401
```
391
402
403
+
</details>
404
+
392
405
To get the right DOM interface you can check pages like [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#technical_summary).
393
406
394
407
Note that for strict type safety, it is necessary to use optional chaining or type guards when accessing `el.value`. This is because the initial ref value is `null` until the component is mounted, and it can also be set to `null` if the referenced element is unmounted by `v-if`.
Sometimes you might need to annotate a template ref for a child component in order to call its public method. For example, we have a `MyModal` child component with a method that opens the modal:
399
-
400
-
```vue
401
-
<!-- MyModal.vue -->
402
-
<script setup lang="ts">
403
-
import { ref } from 'vue'
404
-
405
-
const isContentShown = ref(false)
406
-
const open = () => (isContentShown.value = true)
411
+
With Vue 3.5 and `@vue/language-tools` 2.1 (powering both the IDE language service and `vue-tsc`), the type of refs created by `useTemplateRef()` in SFCs can be **automatically inferred** for static refs based on what element or component the matching `ref` attribute is used on.
407
412
408
-
defineExpose({
409
-
open
410
-
})
411
-
</script>
412
-
```
413
+
In cases where auto-inference is not possible (e.g. non-SFC usage or dynamic components), you can still cast the template ref to an explicit type via the generic argument.
413
414
414
-
In order to get the instance type of `MyModal`, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type:
415
+
In order to get the instance type of an imported component, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type:
In cases where the exact type of the component isn't available or isn't important, `ComponentPublicInstance` can be used instead. This will only include properties that are shared by all components, such as `$el`:
0 commit comments