ホームページ >ウェブフロントエンド >Vue.js >vue3 が ts InstanceType と組み合わせた ref インスタンスを取得する問題を解決する方法

vue3 が ts InstanceType と組み合わせた ref インスタンスを取得する問題を解決する方法

WBOY
WBOY転載
2023-05-20 22:59:321748ブラウズ

    vue3 ref インスタンスを取得し、それを ts の InstanceType と結合します。

    テンプレート参照がある場合がありますが、それらを使用する場合、ts プロンプトは表示されません。コンポーネントが渡すプロンプトはありません。defineExpose によって公開されるメソッド名は、あまり影響はありませんが、解決または解決できます~

    <!-- MyModal.vue -->
    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
    
    const sayHello = () => (console.log(&#39;我会说hello&#39;))
    
    defineExpose({
      sayHello
    })
    </script>

    その後、親レベルでそれを使用します。 MyModalRef.value を入力すると、sayHello 関数プロンプトがないことがわかります。そのため、この時点では、InstanceType ツール タイプを使用してインスタンス タイプを取得する必要があります

    <!-- App.vue -->
    <script setup lang="ts">
    import MyModal from &#39;./MyModal.vue&#39;
    const MyModalRef = ref()
    
    const handleOperation = () => {
      MyModalRef.value.sayHello
    }
    </script>

    vue3 が ts InstanceType と組み合わせた ref インスタンスを取得する問題を解決する方法

    Use InstanceType ツール タイプを使用してインスタンス タイプを取得します:

    <!-- MyModal.vue -->
    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
    
    const sayHello = () => (console.log(&#39;我会说hello&#39;))
    
    defineExpose({
      open
    })
    </script>

    Parent use

    <!-- App.vue -->
    <script setup lang="ts">
    import MyModal from &#39;./MyModal.vue&#39;
    
    const MyModalRef = ref<InstanceType<typeof MyModal> | null>(null)
    
    const handleOperation = () => {
      MyModalRef.value?.sayHello()
    }
    </script>

    プロンプトが表示されても、InstanceType を使用するように求めるプロンプトがまだないようですが、間違った内容を入力してもエラーは発生しませんコンパイル前に報告されました...しかし、Vue 公式がこれを言ったので、彼の言うことを聞いてください (実際、私は通常使用しませんが、これも学びました)

    @vue 公式 API はコンポーネント テンプレート参照型に注釈を付けます

    vue3 コンポーネントの TS タイプに注釈を付ける方法

    Vue3 と TS は、間違いなく今年最も人気のあるフロントエンド テクノロジです。多くの企業が新しいプロジェクトの開発に Vue3 TS Vite を組み合わせて使用​​しています。以下は書き直された文です: Vue3 コンポーネントで Composition-Api を TS タイプと組み合わせて使用​​する方法を共有します。

    プロパティの型に注釈を付ける

    <script setup lang="ts">
    const props = defineProps({
      foo: { type: String, required: true },
      bar: Number
    })
     
    props.foo // string
    props.bar // number / undefined
    </script>

    defineProps() に渡されるパラメータが実行時 props オプションとして使用されるため、これは実行時宣言と呼ばれます。

    2 番目の方法は、ジェネリック パラメーターを使用して props の型を定義することで、より直接的です:

    <script setup lang="ts">
    const props = defineProps<{
      foo: string
      bar?: number
    }>()
    </script>
     
    /* or
    <sctipt setup lang="ts">
    interface Props {
      foo: string
      bar?: number
    }
    const props = defineProps<Props>()
    </script>
    */

    コンパイラーは型パラメーターを推定し、対応する実行時オプションを生成しようとします。このアプローチは次のとおりです。型ベース宣言と呼ばれます。このアプローチの欠点は、props のデフォルト値を定義する機能が失われることです。 withDefaults コンパイラを使用すると、この問題を解決できます。

    interface Props {
      msg?: string
      labels?: string[]
    }
     
    const props = withDefaults(defineProps<Props>(), {
      msg: &#39;hello&#39;,
      label: () => [&#39;one&#39;, &#39;two&#39;]
    })

    上記のコードは、ランタイム プロパティの同等のデフォルト オプションにコンパイルされます。

    Non

    import { defineComponent } from &#39;vue&#39;
     
    export default defineComponent({
      props: {
        message: String
      },
      setup(props){
        props.message // 类型:string
      }
    })

    エミットの型に注釈を付ける

    では、ランタイムを使用してエミット関数の型アノテーションを宣言することもできます。または、型宣言に基づいて:

    <script setup lang="ts">
    // 运行时
    const emit = defineEmits([&#39;change&#39;, &#39;update&#39;])
     
    //基于类型
    const emit = defineEmits<{
      (e: &#39;change&#39;, id: number): void
      (e: &#39;update&#39;, value: string): void
    }>()
    </script>

    型ベースの宣言により、トリガーされるイベントの型をより詳細に制御できることがわかります。

    が使用されていない場合、defineComponent() は、エミット オプションに基づいて、セットアップ コンテキストで公開されるエミット関数のタイプを推測することもできます。

    import { defineComponent } from &#39;vue&#39;
     
    export default definComponent({
      emits: [&#39;change&#39;],
      setup(props, { emit }) {
        emit(&#39;change&#39;) //类型检查 / 自动补全
      }
    })

    は ref() アノテーションのタイプです。

    デフォルトの派生タイプ

    ref は、初期化中の値に基づいてそのタイプを自動的に派生します:

    import { ref } from &#39;vue&#39;
     
    // 推导出的类型:Ref<number>
     
    const year = ref(2022)
     
    // TS Error: Type &#39;string&#39; is not assignable to type &#39;number&#39;.
    year.value = &#39;2022&#39;

    Specifyインターフェイスを介した型

    場合によっては、ref の値に対してより複雑な型を指定することができます。Ref インターフェイスを使用できます:

    import { ref } from &#39;vue&#39;
    import type { Ref } from &#39;vue&#39;
     
    const year: Ref<string | number> = ref(2022)
    year.value = 2022 //成功

    ジェネリックスを介して型を指定します

    または、 ref () を呼び出してデフォルトの導出動作をオーバーライドする場合:

    // 得到的类型:Ref<string | number>
    const year = ref<string | number>(&#39;2022&#39;)
    year.value = 2022 //成功

    ジェネリック パラメーターを指定しても初期値を指定しない場合、最終結果は未定義の共用体型を含む値になります。 ##

    // 推导得到的类型:Ref<number | undefined>
    const n = ref<number>()

    は reactive() のアノテーション タイプです。

    デフォルトの導出タイプ

    reactive() はパラメータからも暗黙的に型を導出します:

    import { reactive } from &#39;vue&#39;
     
    //推导得到的类型:{ title: string }
    const book = reactive({ title: &#39;Vue 3 指引&#39;})

    Specifyインターフェイスを介した型

    リアクティブ変数の型を明示的に指定するには、次のインターフェイスを使用できます。

    import { reactive } from &#39;vue&#39;
     
    interface Book {
      title: string
      year?: number
    }
     
    const book: Book = reactive({ title: &#39;Vue 3 指引&#39; })

    computed() の型に注釈を付ける

    デフォルトの導出型

    computed() は、計算関数の戻り値から型を自動的に推定します。

    import { ref, computed } from &#39;vue&#39;
    const count = ref(0)
     
    // 推导得到的类型:ComputedRef<number>
    const double = computed(() => count.value * 2)
     
    // TS Error: Property &#39;split&#39; does not exist on type &#39;number&#39;
    const result = double.value.split(&#39;&#39;)

    ジェネリックスを通じて型を指定します

    const double = component<number>(() => {
      // 若返回值不是 number 类型则会报错
    })

    イベント処理関数の型に注釈を付けます。

    ネイティブ DOM イベントを処理する場合、イベント処理関数のパラメーターは次のような型で正しくマークされる必要があります。

    <script srtup lang="ts">
    function handleChange(event) {
      // `event` 隐式地标注为 `any`类型
      console.log(event.target.value)
    }
    </script>
     
    <template>
      <input type="text" @change="handleChange" />
    </template>

    型のマークがない場合、イベント パラメーターは自動的に認識されます。どのタイプでも構いません。 tsconfig.json で "strict": true または "noImplicitAny": true が構成されている場合も、TS エラーが発生します。したがって、イベント ハンドラー関数パラメーターのタイプに明示的に注釈を付けることをお勧めします。さらに、イベントでプロパティを明示的にキャストする必要がある場合があります。

    function handleChange(event: Event) {
      console.log((event.target as HTMLInputElement).value)
    }

    provide / inject のタイプに注釈を付けます

    provide と inject は通常、別のコンポーネントで実行されます。注入された値の型を正しくマークするために、Vue は Injectionkey インターフェイスを提供します。これは Symbol から継承されたジェネリック型であり、プロバイダーとコンシューマー間で注入された値の型を同期するために使用できます。複数のコンポーネントでインポートできるように、注入されたキー タイプを別のファイルに置くことをお勧めします。

    文字列を使用してキーを挿入する場合、注入された値のタイプは不明であるため、宣言は汎用パラメーターを使用して表示する必要があります:

    const foo = inject<string>(&#39;key&#39;) // 类型:string | undefined

    由于提供者在运行时可能没有提供这个值,因此请注意注入的值可能仍然是未定义的。移除 undefined 类型的方法是提供一个默认值

    const foo = inject<string>(&#39;foo&#39;, &#39;bar&#39;) // 类型:string

    如果你确定该值始终被提供,则还可以强制转换该值:

    const foo = inject(&#39;foo&#39;) as string

    为 dom 模板引用标注类型

    模板 ref 需要通过一个显式指定的泛型参数和一个初始值 null 来创建:

    <script setup lang="ts">
    import { ref, onMounted } from &#39;vue&#39;
    const el = ref<HTMLInputElement | null>(null)
     
    onMounted(() => {
      el.value?.focus()
    })
    </script>
     
    <template>
      <input ref="el" />
    </template>

    为了严格的类型安全,请使用可选链或类型守卫来访问 el.value。这是因为直到组件被挂载前,这个 ref 的值都是初始的 null,并且 v-if 将引用的元素卸载时也会被设置为 null。

    为组件模板引用标注类型

    有时候,我们需要为一个子组件添加一个模板引用(template reference),以便可以调用它公开的方法。举个例子,我们有一个 MyModal 子组件,其中包含一个用于打开模态框的方法:

    <script setup lang="ts">
    import { ref } from &#39;vue&#39;
     
    const isContentShown = ref(false)
    const open = () => (isContentShow.value = true)
     
    defineExpose({
      open
    })
    </script>

    为了获取 MyModal 的类型,我们首先需要通过 typeof 得到其类型,再使用 TypeScript 内置的 InstanceType 工具类型来获取其实例类型:

    <script>
    import MyModal from &#39;./MyModal.vue&#39;
     
    const modal = ref<InstanceType<typeof MyModal > | null>(null)
    const openModal = () => {
      modal.value?.open()
    }
    </script>

    以上がvue3 が ts InstanceType と組み合わせた ref インスタンスを取得する問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。