Maison >interface Web >Voir.js >Comment résoudre le problème de vue3 obtenant une instance de référence combinée avec ts InstanceType
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 'vue' const sayHello = () => (console.log('我会说hello')) 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 './MyModal.vue' const MyModalRef = ref() const handleOperation = () => { MyModalRef.value.sayHello } </script>
Utilisez le type d'outil InstanceType pour obtenir son type d'instance :
<!-- MyModal.vue --> <script setup lang="ts"> import { ref } from 'vue' const sayHello = () => (console.log('我会说hello')) defineExpose({ open }) </script>
Utilisation parentale
<!-- App.vue --> <script setup lang="ts"> import MyModal from './MyModal.vue' 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
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.
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: 'hello', label: () => ['one', 'two'] })
Le code ci-dessus sera compilé dans l'option par défaut des accessoires d'exécution équivalents.
Si
import { defineComponent } from 'vue' export default defineComponent({ props: { message: String }, setup(props){ props.message // 类型:string } })
Utiliser
Dans
<script setup lang="ts"> // 运行时 const emit = defineEmits(['change', 'update']) //基于类型 const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', 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 'vue' export default definComponent({ emits: ['change'], setup(props, { emit }) { emit('change') //类型检查 / 自动补全 } })
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 'vue' // 推导出的类型:Ref<number> const year = ref(2022) // TS Error: Type 'string' is not assignable to type 'number'. year.value = '2022'Spécifier les types via les interfacesParfois, nous pouvons vouloir spécifier un type plus complexe pour la valeur dans la réf. 🎜#
import { ref } from 'vue' import type { Ref } from 'vue' 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>('2022') 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()
import { reactive } from 'vue' //推导得到的类型:{ title: string } const book = reactive({ title: 'Vue 3 指引'})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 'vue' interface Book { title: string year?: number } const book: Book = reactive({ title: 'Vue 3 指引' })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 'vue' const count = ref(0) // 推导得到的类型:ComputedRef<number> const double = computed(() => count.value * 2) // TS Error: Property 'split' does not exist on type 'number' const result = double.value.split('')Spécifier le type via des génériques
const double = component<number>(() => { // 若返回值不是 number 类型则会报错 })Annoter le type du fonction de traitement d'événementsLors 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>
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 'vue' import type { Injectiokey } from 'vue' const key = Symbol() as Injectionkey<string> provide(key,'foo') // 若提供的是非字符串值会导致错误 const foo = inject(key) // foo 的类型: string | undefined
const foo = inject<string>('key') // 类型:string | undefined
由于提供者在运行时可能没有提供这个值,因此请注意注入的值可能仍然是未定义的。移除 undefined 类型的方法是提供一个默认值
const foo = inject<string>('foo', 'bar') // 类型:string
如果你确定该值始终被提供,则还可以强制转换该值:
const foo = inject('foo') as string
模板 ref 需要通过一个显式指定的泛型参数和一个初始值 null 来创建:
<script setup lang="ts"> import { ref, onMounted } from 'vue' 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 'vue' const isContentShown = ref(false) const open = () => (isContentShow.value = true) defineExpose({ open }) </script>
为了获取 MyModal 的类型,我们首先需要通过 typeof 得到其类型,再使用 TypeScript 内置的 InstanceType 工具类型来获取其实例类型:
<script> import MyModal from './MyModal.vue' 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!