Heim >Web-Frontend >View.js >So lösen Sie das Problem, dass vue3 eine Referenzinstanz in Kombination mit ts InstanceType erhält
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 'vue' const sayHello = () => (console.log('我会说hello')) 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 './MyModal.vue' const MyModalRef = ref() const handleOperation = () => { MyModalRef.value.sayHello } </script>
Verwenden Sie den InstanceType-Tooltyp, um seinen Instanztyp abzurufen:
<!-- MyModal.vue --> <script setup lang="ts"> import { ref } from 'vue' const sayHello = () => (console.log('我会说hello')) defineExpose({ open }) </script>
Parent use
<!-- 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>
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
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.
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: 'hello', label: () => ['one', 'two'] })
Der obige Code wird in die Standardoption der entsprechenden Laufzeit-Requisiten kompiliert.
Wenn
import { defineComponent } from 'vue' export default defineComponent({ props: { message: String }, setup(props){ props.message // 类型:string } })
Nicht
Wenn
<script setup lang="ts"> // 运行时 const emit = defineEmits(['change', 'update']) //基于类型 const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', 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 'vue' export default definComponent({ emits: ['change'], setup(props, { emit }) { emit('change') //类型检查 / 自动补全 } })Typen über Schnittstellen angebenManchmal 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 'vue' // 推导出的类型:Ref<number> const year = ref(2022) // TS Error: Type 'string' is not assignable to type 'number'. year.value = '2022'
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 'vue' import type { Ref } from 'vue' 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>('2022') 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 'vue' //推导得到的类型:{ title: string } const book = reactive({ title: 'Vue 3 指引'})
import { reactive } from 'vue' interface Book { title: string year?: number } const book: Book = reactive({ title: 'Vue 3 指引' })Geben Sie den Typ durch Generics an
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('')Annotieren Sie den Typ des EreignisverarbeitungsfunktionBei 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) }
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>
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!