Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk menyelesaikan masalah vue3 mendapatkan contoh ref digabungkan dengan ts InstanceType

Bagaimana untuk menyelesaikan masalah vue3 mendapatkan contoh ref digabungkan dengan ts InstanceType

WBOY
WBOYke hadapan
2023-05-20 22:59:321692semak imbas

    vue3 mendapat contoh ref dan menggabungkannya dengan InstanceType ts

    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 &#39;vue&#39;
    
    const sayHello = () => (console.log(&#39;我会说hello&#39;))
    
    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 &#39;./MyModal.vue&#39;
    const MyModalRef = ref()
    
    const handleOperation = () => {
      MyModalRef.value.sayHello
    }
    </script>

    Bagaimana untuk menyelesaikan masalah vue3 mendapatkan contoh ref digabungkan dengan ts InstanceType

    Gunakan jenis alat InstanceType untuk mendapatkan jenis instancenya:

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

    Ibu bapa menggunakan

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

    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

    Cara menganotasi jenis TS untuk komponen vue3

    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.

    Jenis anotasi untuk prop

    Gunakan

    Apabila menggunakan , fungsi makro defineProps() menyokong penolakan daripada parameternya Jenis:

    <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: &#39;hello&#39;,
      label: () => [&#39;one&#39;, &#39;two&#39;]
    })

    Kod di atas akan disusun ke dalam pilihan lalai prop masa jalan yang setara.

    Persediaan bukan

    Jika tidak digunakan, defineComponent() mesti digunakan untuk mendayakan potongan jenis untuk prop. Jenis objek props disimpulkan daripada pilihan props dan digunakan untuk menghantar ke fungsi setup().

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

    Anotasi jenis pancaran

    Gunakan

    Dalam , anotasi jenis fungsi emit juga boleh menggunakan pengisytiharan masa jalan atau berdasarkan pada pengisytiharan Jenis:

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

    Kita dapat melihat bahawa pengisytiharan berasaskan jenis membolehkan kita mempunyai kawalan yang lebih terperinci ke atas jenis peristiwa yang dicetuskan.

    Persediaan bukan

    Jika tidak digunakan, defineComponent() juga boleh menyimpulkan jenis fungsi pancaran yang didedahkan dalam konteks persediaan berdasarkan pancaran pilihan:

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

    ialah jenis anotasi ref()

    Jenis terbitan lalai

    ref akan secara automatik menyimpulkan jenisnya berdasarkan nilai semasa permulaan:

    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;

    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 &#39;vue&#39;
    import type { Ref } from &#39;vue&#39;
     
    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>(&#39;2022&#39;)
    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 &#39;vue&#39;
     
    //推导得到的类型:{ title: string }
    const book = reactive({ title: &#39;Vue 3 指引&#39;})

    Tentukan jenis melalui antara muka

    Untuk menyatakan secara eksplisit jenis pembolehubah reaktif, kita boleh menggunakan antara muka:

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

    Jenis anotasi untuk dikira()

    Jenis terbitan lalai

    computed() akan secara automatik menyimpulkan jenis daripada nilai pulangan fungsi pengiraannya:

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

    Nyatakan jenis melalui generik

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

    Annotate jenis fungsi pemprosesan acara

    Apabila 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 &#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

    Ia 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>(&#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>

    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!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam