Heim  >  Artikel  >  Web-Frontend  >  So lösen Sie das Problem, dass vue3 eine Referenzinstanz in Kombination mit ts InstanceType erhält

So lösen Sie das Problem, dass vue3 eine Referenzinstanz in Kombination mit ts InstanceType erhält

WBOY
WBOYnach vorne
2023-05-20 22:59:321692Durchsuche

    vue3 erhält die Referenzinstanz kombiniert mit dem InstanceType von ts

    Manchmal haben wir Vorlagenreferenzen, aber wenn wir sie verwenden, ts-Eingabeaufforderungen Aber es funktioniert nicht. Es gibt keine Eingabeaufforderung für den Methodennamen, der von der Komponente über defineExpose bereitgestellt wird. Obwohl dies keine großen Auswirkungen hat, kann es gelöst oder gelöst werden~

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

    Dann verwenden wir Geben Sie es auf der übergeordneten Ebene ein und vervollständigen Sie die Eingabe MyModalRef.value. Wir werden feststellen, dass es keine Eingabeaufforderung für die Funktion sayHello gibt. Daher müssen wir zu diesem Zeitpunkt den Werkzeugtyp InstanceType verwenden, um seinen Instanztyp abzurufen

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

    So lösen Sie das Problem, dass vue3 eine Referenzinstanz in Kombination mit ts InstanceType erhält

    Verwenden Sie den InstanceType-Tooltyp, um seinen Instanztyp abzurufen:

    <!-- 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>

    Es scheint, dass es immer noch keine gibt Wenn Sie dazu aufgefordert werden, werden Sie aufgefordert, InstanceType zu verwenden und dann den falschen Inhalt einzugeben. Vor der Kompilierung wird kein Fehler gemeldet ..., aber vue offiziell Hören Sie ihm einfach zu (tatsächlich verwende ich es normalerweise nicht, aber ich habe es getan). habe es gelernt)

    @vue offizielle API kommentiert Komponentenvorlagen-Referenztypen

    Anleitung Die vue3-Komponente ist mit TS-Typ markiert

    Vue3 und TS sind definitiv zu den beliebtesten Frontend-Technologien in diesem Jahr. Viele Unternehmen nutzen die Kombination Vue3 + TS + Vite, um neue Projekte zu entwickeln. Das Folgende ist der umgeschriebene Satz: Teilen Sie mit, wie Sie Composition-Api in Kombination mit TS-Typen in Vue3-Komponenten verwenden.

    Kommentieren Sie die Art der Requisiten.

    Verwenden Sie

    Bei Verwendung von

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

    Dies wird als Laufzeitdeklaration bezeichnet, da die an defineProps() übergebenen Parameter als Laufzeit-Requisitenoptionen verwendet werden.

    Die zweite Möglichkeit besteht darin, den Typ der Requisiten über generische Parameter zu definieren, was direkter ist:

    <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>
    */

    Der Compiler versucht, die Typparameter abzuleiten und den entsprechenden Lauf zu generieren Option wird dieser Ansatz als typbasierte Deklaration bezeichnet. Der Nachteil dieses Ansatzes besteht darin, dass die Möglichkeit verloren geht, Standardwerte für Requisiten zu definieren. Die Verwendung des withDefaults-Compilers kann dieses Problem lösen

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

    Der obige Code wird in die Standardoption der entsprechenden Laufzeit-Requisiten kompiliert.

    Nicht

    Wenn

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

    Wir können sehen, dass die typbasierte Deklaration uns eine detailliertere Kontrolle über die Art der ausgelösten Ereignisse ermöglicht.

    Nicht

    Wenn nicht verwendet wird, kann defineComponent() auch den Typ der im Setup-Kontext bereitgestellten Emit-Funktion ableiten die Option „emittiert“. :

    <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>

    ist der Annotationstyp ref()

    Der Standardableitungstyp

    ref leitet seinen Typ automatisch basierend auf ab Wert während der Initialisierung: #🎜🎜 #

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

    Typen über Schnittstellen angeben

    Manchmal möchten wir möglicherweise einen komplexeren Typ für den Wert in ref angeben. Sie können die Ref-Schnittstelle verwenden: #🎜 🎜#
    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;

    Geben Sie den Typ über Generika an.

    Alternativ können Sie beim Aufruf von ref() einen generischen Parameter übergeben, um das Standardableitungsverhalten zu überschreiben:

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

    Wenn Sie Geben Sie einen generischen Typparameter an, aber es wird kein Anfangswert angegeben. Das Endergebnis ist dann ein Union-Typ, der undefiniert enthält:

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

    ist der Annotationstyp für reactive()

    Default Ableitungstyp# 🎜🎜#

    reactive() leitet den Typ auch implizit aus seinem Argument ab:

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

    Geben Sie den Typ über die Schnittstelle an

    Um a explizit anzugeben reaktiv Für den Typ der Variablen können wir die Schnittstelle verwenden:

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

    , um den Typ von berechnet() zu markieren

    Der Standardableitungstyp

    berechnet() wird automatisch daraus abgeleitet. Der Typ wird aus dem Rückgabewert der Berechnungsfunktion abgeleitet:

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

    Geben Sie den Typ durch Generics an

    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;)

    Annotieren Sie den Typ des Ereignisverarbeitungsfunktion

    Bei der Verarbeitung des nativen DOM-Ereignisses sollten die Parameter der Ereignisverarbeitungsfunktion korrekt mit Typen gekennzeichnet sein, z. B.:

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

    Wenn vorhanden Keine Typmarkierung, der Ereignisparameter wird automatisch als beliebiger Typ erkannt. Dies führt auch zu einem TS-Fehler, wenn „strict“: true oder „noImplicitAny“: true in tsconfig.json konfiguriert ist. Daher wird empfohlen, die Typen der Parameter der Event-Handler-Funktion explizit mit Anmerkungen zu versehen. Darüber hinaus müssen Sie möglicherweise die Eigenschaften explizit auf das Ereignis umwandeln:

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

    Annotieren Sie den Typ für Provide/Inject.

    Provide und Inject werden normalerweise in verschiedenen Komponenten ausgeführt. Um den Typ der injizierten Werte korrekt zu markieren, stellt Vue eine Schnittstelle „Injectionkey“ bereit, bei der es sich um einen von Symbol geerbten generischen Typ handelt, der zum Synchronisieren des Typs der injizierten Werte zwischen Anbietern und Verbrauchern verwendet werden kann:

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

    Es wird empfohlen, den Typ des injizierten Schlüssels in einer separaten Datei abzulegen, damit er von mehreren Komponenten importiert werden kann.

    Bei Verwendung einer Zeichenfolge zum Einfügen eines Schlüssels ist der Typ des eingegebenen Werts unbekannt und die Deklaration muss über generische Parameter angezeigt werden:

    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>

    Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem, dass vue3 eine Referenzinstanz in Kombination mit ts InstanceType erhält. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen