Skip to content

Commit 7611560

Browse files
committed
docs: Update usage of useTemplateRef() in composition API guide
1 parent c5dd319 commit 7611560

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

src/guide/typescript/composition-api.md

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,17 @@ const foo = inject('foo') as string
371371

372372
## テンプレート参照の型付け {#typing-template-refs}
373373

374+
Vue 3.5 と `@vue/language-tools` 2.1(IDE の言語サービスと `vue-tsc` の両方をサポート)では、SFC の `useTemplateRef()` で作成された `ref` の型は、`ref` 属性が使用されている要素またはコンポーネントに基づいて、静的な `ref` の型を *自動的に推論* できます。
375+
376+
自動推論が不可能な場合でも、`generic` 引数を使用してテンプレート参照を明示的な型にキャストすることができます:
377+
378+
```ts
379+
const el = useTemplateRef<HTMLInputElement>(null)
380+
```
381+
382+
<details>
383+
<summary>3.5 以前の使用方法</summary>
384+
374385
テンプレート参照は、明示的な型引数と初期値 `null` を指定して作成されます:
375386

376387
```vue
@@ -389,50 +400,45 @@ onMounted(() => {
389400
</template>
390401
```
391402

403+
</details>
404+
392405
適切な DOM インターフェースを取得するには、[MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input#技術的概要) のようなページを確認してください。
393406

394407
厳密な型安全性のために、`el.value` にアクセスする際には、オプショナルチェーンもしくは型ガードをする必要があります。なぜなら、コンポーネントがマウントされるまでは ref の初期値は `null` であり、参照されていた要素が `v-if` によってアンマウントされた場合にも `null` にセットされる可能性があるからです。
395408

396409
## コンポーネントのテンプレート参照の型付け {#typing-component-template-refs}
397410

398-
時に、子コンポーネントのパブリックメソッドを呼ぶために、子コンポーネントのテンプレート参照に型づけする必要があるかもしれません。例えば、モーダルを開くメソッドを持つ `MyModal` という子コンポーネントがあるとします:
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+
Vue 3.5 と `@vue/language-tools` 2.1(IDE の言語サービスと `vue-tsc` の両方をサポート)では、SFC の `useTemplateRef()` で作成された `ref` の型は、`ref` 属性が使用されている要素またはコンポーネントに基づいて、静的な `ref` の型を *自動的に推論* できます。
407412

408-
defineExpose({
409-
open
410-
})
411-
</script>
412-
```
413+
自動推論が不可能な場合(例えば、SFC 以外の使用や動的コンポーネントの場合)でも、`generic` 引数を使用してテンプレート参照を明示的な型にキャストすることができます。
413414

414-
`MyModal` のインスタンスの型を得るために、まず `typeof` によって型を取得し、次に TypeScript の組み込みユーティリティーの `InstanceType` を使って型を抽出する必要があります:
415+
インポートされたコンポーネントのインスタンスの型を得るために、まず `typeof` によって型を取得し、次に TypeScript の組み込みユーティリティーの `InstanceType` を使って型を抽出する必要があります:
415416

416417
```vue{5}
417418
<!-- App.vue -->
418419
<script setup lang="ts">
419-
import MyModal from './MyModal.vue'
420+
import { useTemplateRef } from 'vue'
421+
import Foo from './Foo.vue'
422+
import Bar from './Bar.vue'
420423
421-
const modal = ref<InstanceType<typeof MyModal> | null>(null)
424+
type FooType = InstanceType<typeof Foo>
425+
type BarType = InstanceType<typeof Bar>
422426
423-
const openModal = () => {
424-
modal.value?.open()
425-
}
427+
const compRef = useTemplateRef<FooType | BarType>('comp')
426428
</script>
429+
430+
<template>
431+
<component :is="Math.random() > 0.5 ? Foo : Bar" ref="comp" />
432+
</template>
427433
```
428434

429435
コンポーネントの正確な型がわからない場合や重要でない場合は、代わりに `ComponentPublicInstance` を使用できます。この場合、`$el` のようなすべてのコンポーネントで共有されているプロパティのみが含まれます:
430436

431437
```ts
432-
import { ref } from 'vue'
438+
import { useTemplateRef } from 'vue'
433439
import type { ComponentPublicInstance } from 'vue'
434440

435-
const child = ref<ComponentPublicInstance | null>(null)
441+
const child = useTemplateRef<ComponentPublicInstance | null>(null)
436442
```
437443

438444
参照されるコンポーネントが[ジェネリックコンポーネント](/guide/typescript/overview.html#generic-components)の場合、例えば `MyGenericModal` の場合:
@@ -457,15 +463,16 @@ defineExpose({
457463
```vue
458464
<!-- App.vue -->
459465
<script setup lang="ts">
466+
import { useTemplateRef } from 'vue'
460467
import MyGenericModal from './MyGenericModal.vue'
468+
import type { ComponentExposed } from 'vue-component-type-helpers'
461469
462-
import type { ComponentExposed } from 'vue-component-type-helpers';
463-
464-
const modal = ref<ComponentExposed<typeof MyModal> | null>(null)
470+
const modal = useTemplateRef<ComponentExposed<typeof MyModal>>(null)
465471
466472
const openModal = () => {
467473
modal.value?.open('newValue')
468474
}
469475
</script>
470476
```
471477

478+
なお、`@vue/language-tools` 2.1 以降では、静的テンプレート参照の型は自動的に推論されるので、上記はエッジケースでのみ必要となります。

0 commit comments

Comments
 (0)