Rumah >hujung hadapan web >View.js >Bagaimana untuk menyelesaikan masalah vue3 mendapatkan contoh ref digabungkan dengan ts InstanceType
Kadangkala kami mempunyai rujukan templat, tetapi apabila menggunakannya, gesaan ts tidak berfungsi, dan tiada gesaan untuk komponen lulus Nama kaedah yang didedahkan oleh defineExpose, walaupun ini tidak begitu berpengaruh, ia boleh diselesaikan atau diselesaikan~
<!-- MyModal.vue --> <script setup lang="ts"> import { ref } from 'vue' const sayHello = () => (console.log('我会说hello')) defineExpose({ sayHello }) </script>
Kemudian kami menggunakannya di peringkat induk memasukkan MyModalRef.value, kami akan mendapati bahawa tiada gesaan fungsi sayHello, jadi pada masa ini Kami perlu menggunakan jenis alat InstanceType untuk mendapatkan jenis instancenya
<!-- App.vue --> <script setup lang="ts"> import MyModal from './MyModal.vue' const MyModalRef = ref() const handleOperation = () => { MyModalRef.value.sayHello } </script>
Gunakan jenis alat InstanceType untuk mendapatkan jenis instancenya:
<!-- MyModal.vue --> <script setup lang="ts"> import { ref } from 'vue' const sayHello = () => (console.log('我会说hello')) defineExpose({ open }) </script>
Ibu bapa menggunakan
<!-- 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>
Nampaknya masih tiada gesaan untuk menggunakan InstanceType apabila digesa, dan kemudian masukkan kandungan yang salah dan tiada ralat dilaporkan sebelum penyusunan..., tetapi pegawai Vue berkata ini, kemudian dengar sahaja dia (sebenarnya, saya biasanya tidak menggunakannya, tetapi Juga belajar)
@vue official API mencatatkan jenis rujukan templat komponen
Vue3 dan TS pastinya merupakan teknologi bahagian hadapan yang paling popular tahun ini. Banyak syarikat menggunakan gabungan Vue3 + TS + Vite untuk membangunkan projek baharu. Berikut ialah ayat yang ditulis semula: Kongsi cara menggunakan Composition-Api digabungkan dengan jenis TS dalam komponen Vue3.
Gunakan
Apabila menggunakan
<script setup lang="ts"> const props = defineProps({ foo: { type: String, required: true }, bar: Number }) props.foo // string props.bar // number / undefined </script>
Ini dipanggil pengisytiharan masa jalan kerana parameter yang dihantar kepada defineProps() akan digunakan sebagai pilihan prop masa jalan.
Cara kedua ialah menentukan jenis prop melalui parameter generik, yang lebih langsung:
<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> */
Pengkompil akan cuba menyimpulkan parameter jenis dan menjana pilihan masa jalan yang sepadan, yang Pendekatan ini dipanggil pengisytiharan berasaskan jenis. Kelemahan pendekatan ini ialah keupayaan untuk menentukan nilai lalai untuk prop hilang. Menggunakan pengkompil withDefaults boleh menyelesaikan masalah ini
interface Props { msg?: string labels?: string[] } const props = withDefaults(defineProps<Props>(), { msg: 'hello', label: () => ['one', 'two'] })
Kod di atas akan disusun ke dalam pilihan lalai prop masa jalan yang setara.
Jika
import { defineComponent } from 'vue' export default defineComponent({ props: { message: String }, setup(props){ props.message // 类型:string } })
Gunakan
Dalam
<script setup lang="ts"> // 运行时 const emit = defineEmits(['change', 'update']) //基于类型 const emit = defineEmits<{ (e: 'change', id: number): void (e: 'update', value: string): void }>() </script>
Kita dapat melihat bahawa pengisytiharan berasaskan jenis membolehkan kita mempunyai kawalan yang lebih terperinci ke atas jenis peristiwa yang dicetuskan.
Persediaan bukan
Jika
import { defineComponent } from 'vue' export default definComponent({ emits: ['change'], setup(props, { emit }) { emit('change') //类型检查 / 自动补全 } })
Jenis terbitan lalai
ref akan secara automatik menyimpulkan jenisnya berdasarkan nilai semasa permulaan:
import { ref } from 'vue' // 推导出的类型:Ref<number> const year = ref(2022) // TS Error: Type 'string' is not assignable to type 'number'. year.value = '2022'
Nyatakan jenis melalui antara muka
Kadangkala kita mungkin mahu menentukan jenis yang lebih kompleks untuk nilai dalam rujukan Anda boleh menggunakan antara muka Rujukan:
import { ref } from 'vue' import type { Ref } from 'vue' const year: Ref<string | number> = ref(2022) year.value = 2022 //成功
Nyatakan jenis melalui generik<.>
Atau, apabila memanggil ref () untuk mengatasi tingkah laku terbitan lalai:// 得到的类型:Ref<string | number> const year = ref<string | number>('2022') year.value = 2022 //成功Jika anda menentukan parameter generik tetapi tidak memberikan nilai awal, hasil akhir akan menjadi nilai yang mengandungi Kesatuan tidak ditentukan jenis:
// 推导得到的类型:Ref<number | undefined> const n = ref<number>()ialah reactive() jenis anotasi Jenis terbitan lalai reactive() juga secara tersirat akan memperoleh jenis daripada parameternya:
import { reactive } from 'vue' //推导得到的类型:{ title: string } const book = reactive({ title: 'Vue 3 指引'})Tentukan jenis melalui antara mukaUntuk menyatakan secara eksplisit jenis pembolehubah reaktif, kita boleh menggunakan antara muka:
import { reactive } from 'vue' interface Book { title: string year?: number } const book: Book = reactive({ title: 'Vue 3 指引' })Jenis anotasi untuk dikira()Jenis terbitan lalaicomputed() akan secara automatik menyimpulkan jenis daripada nilai pulangan fungsi pengiraannya:
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('')Nyatakan jenis melalui generik
const double = component<number>(() => { // 若返回值不是 number 类型则会报错 })Annotate jenis fungsi pemprosesan acaraApabila memproses peristiwa DOM asli, parameter fungsi pemprosesan acara hendaklah ditanda dengan betul dengan jenis, seperti:
<script srtup lang="ts"> function handleChange(event) { // `event` 隐式地标注为 `any`类型 console.log(event.target.value) } </script> <template> <input type="text" @change="handleChange" /> </template>Apabila tiada tanda jenis, parameter acara akan dikenali secara automatik sebagai mana-mana taip. Ini juga akan menimbulkan ralat TS jika "strict": true atau "noImplicitAny": true dikonfigurasikan dalam tsconfig.json. Oleh itu, adalah disyorkan untuk menganotasi secara eksplisit jenis parameter fungsi pengendali peristiwa. Selain itu, anda mungkin perlu menghantar sifat secara eksplisit pada acara:
function handleChange(event: Event) { console.log((event.target as HTMLInputElement).value) }jenis anotasi untuk menyediakan / menyuntik menyediakan dan menyuntik biasanya dijalankan dalam komponen yang berbeza. Untuk menandakan jenis nilai yang disuntik dengan betul, Vue menyediakan antara muka Injectionkey, yang merupakan jenis generik yang diwarisi daripada Symbol dan boleh digunakan untuk menyegerakkan jenis nilai yang disuntik antara pembekal dan pengguna:
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 | undefinedIa adalah disyorkan untuk meletakkan jenis kunci yang disuntik dalam fail berasingan supaya ia boleh diimport oleh berbilang komponen. Apabila menggunakan rentetan untuk menyuntik kunci, jenis nilai yang disuntik tidak diketahui dan perlu diisytiharkan secara eksplisit melalui parameter generik:
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>
Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan masalah vue3 mendapatkan contoh ref digabungkan dengan ts InstanceType. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!