Maison  >  Article  >  interface Web  >  Comment résoudre le problème de vue3 obtenant une instance de référence combinée avec ts InstanceType

Comment résoudre le problème de vue3 obtenant une instance de référence combinée avec ts InstanceType

WBOY
WBOYavant
2023-05-20 22:59:321691parcourir

    vue3 obtient l'instance ref combinée avec l'InstanceType de ts

    Parfois, nous avons des références de modèles, mais lorsque nous les utilisons, ts invite Mais cela ne fonctionne pas. Il n'y a pas d'invite pour le nom de la méthode exposé par le composant via definitionExpose. Bien que cela n'affecte pas beaucoup, cela peut être résolu ou résolu ~

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

    Ensuite, nous utilisons. au niveau parent et complétez l'entrée MyModalRef.value et nous constaterons qu'il n'y a pas d'invite de fonction sayHello, nous devons donc pour le moment utiliser le type d'outil InstanceType pour obtenir son type d'instance

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

    Comment résoudre le problème de vue3 obtenant une instance de référence combinée avec ts InstanceType

    Utilisez le type d'outil InstanceType pour obtenir son type d'instance :

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

    Utilisation parentale

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

    Il semble qu'il n'y ait toujours pas invite à utiliser InstanceType lorsque vous y êtes invité, puis entrez le mauvais contenu et aucune erreur n'est signalée avant la compilation..., mais vue official Cela dit, écoutez-le (en fait, je ne l'utilise généralement pas, mais j'ai je l'ai appris)

    @vue L'API officielle annote les types de référence de modèle de composant

    Comment Le composant vue3 est marqué du type TS

    Vue3 et TS sont certainement parmi les technologies frontales les plus populaires cette année. De nombreuses entreprises utilisent la combinaison Vue3 + TS + Vite pour développer de nouveaux projets. Voici la phrase réécrite : Partagez comment utiliser Composition-Api combinée avec les types TS dans les composants Vue3.

    Annoter le type d'accessoires

    Utiliser

    Lors de l'utilisation de

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

    C'est ce qu'on appelle une déclaration d'exécution, car les paramètres passés à definitionProps() seront utilisés comme options d'accessoires d'exécution.

    La deuxième façon est de définir le type de props via des paramètres génériques, ce qui est plus direct :

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

    Le compilateur va tenter de déduire les paramètres de type et générer le run correspondant option, cette approche est appelée déclaration basée sur le type. L'inconvénient de cette approche est que la possibilité de définir des valeurs par défaut pour les accessoires est perdue. L'utilisation du compilateur withDefaults peut résoudre ce problème

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

    Le code ci-dessus sera compilé dans l'option par défaut des accessoires d'exécution équivalents.

    Non

    Si

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

    Annoter le type pour les émissions

    Utiliser

    Dans

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

    Nous pouvons voir que la déclaration basée sur le type nous permet d'avoir un contrôle plus fin sur le type d'événements déclenchés.

    Non

    Si

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

    est le type d'annotation ref()

    Le type de dérivation par défaut

    ref déduira automatiquement son type en fonction du valeur lors de l'initialisation : #🎜🎜 #

    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;

    Spécifier les types via les interfaces

    Parfois, nous pouvons vouloir spécifier un type plus complexe pour la valeur dans la réf. 🎜#
    import { ref } from &#39;vue&#39;
    import type { Ref } from &#39;vue&#39;
     
    const year: Ref<string | number> = ref(2022)
    year.value = 2022 //成功

    Spécifiez le type via des génériques

    Vous pouvez également transmettre un paramètre générique lors de l'appel de ref() pour remplacer le comportement de dérivation par défaut :

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

    Si vous spécifiez un paramètre Type générique mais aucune valeur initiale n'est donnée, alors le résultat final sera un type d'union contenant undefined :

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

    est le type d'annotation pour reactive()

    Default derivation type# 🎜🎜#

    reactive() déduira également implicitement le type de son argument :

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

    Spécifiez le type via l'interface

    Pour spécifier explicitement un réactif Pour le type de variables, on peut utiliser l'interface :

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

    pour marquer le type de calculée()

    Le type de dérivation par défaut

    computing() en sera automatiquement dérivé Le type se déduit de la valeur de retour de la fonction de calcul :

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

    Spécifier le type via des génériques

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

    Annoter le type du fonction de traitement d'événements

    Lors du traitement du natif Lors de l'exécution d'un événement DOM, les paramètres de la fonction de traitement d'événements doivent être correctement marqués avec des types, tels que :

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

    Quand il y a aucun marquage de type, le paramètre d'événement sera automatiquement reconnu comme n'importe quel type. Cela générera également une erreur TS si « strict » : true ou « noImplicitAny » : true est configuré dans tsconfig.json. Par conséquent, il est recommandé d’annoter explicitement les types de paramètres de fonction du gestionnaire d’événements. De plus, vous devrez peut-être convertir explicitement les propriétés sur l'événement :

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

    Annoter le type pour provide / inject

    provide et inject s'exécuteront généralement dans différents composants. Pour marquer correctement le type de valeurs injectées, Vue fournit une interface Injectionkey, qui est un type générique hérité de Symbol et peut être utilisée pour synchroniser le type de valeurs injectées entre les fournisseurs et les consommateurs :

    import { provide, inject } from &#39;vue&#39;
    import type { Injectiokey } from &#39;vue&#39;
     
    const key = Symbol() as Injectionkey<string>
    provide(key,&#39;foo&#39;) // 若提供的是非字符串值会导致错误
     
    const foo = inject(key) // foo 的类型: string | undefined

    Il est recommandé de placer le type de clé injecté dans un fichier séparé afin qu'il puisse être importé par plusieurs composants.

    Lors de l'utilisation d'une chaîne pour injecter une clé, le type de la valeur injectée est inconnu et la déclaration doit être affichée via des paramètres génériques :

    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>

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer