vue3 setup script+Typescript实战用法(二)——ref、defineProps、defineEmits

·  阅读 10049
vue3 setup script+Typescript实战用法(二)——ref、defineProps、defineEmits

ref

定义一个子组件,想要通过ref拿到子组件的方法或者实例时,ts编译不通过,此时可以这样做

子组件:

//son.vue

<template>
    <h1>son</h1>
</template>

<script lang="ts" setup>
const count = 0

const fn = () => {
    console.log('-----------子组件的方法-----------')
}

defineExpose({ fn, count })
</script>
复制代码

父组件:

//father.vue

<template>
    <Son ref="sonRef" />
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import Son from './son.vue'

interface sonData {
    fn: () => void
    count: number
}

const sonRef = ref<InstanceType<typeof Son> & sonData>()

const a = onMounted(() => {
    console.log(sonRef.value?.$el)
    console.log(sonRef.value?.fn)
})

</script>
复制代码

InstanceType<typeof Son>只有组件默认的方法,没有私有方法和数据,所以要对这个数据类型做一个扩展,自定义子组件的方法数据类型,再合并,这样就可以拿到子组件的实例和方法。

如果只想拿到子组件的数据的方法,其它的公有方法不需要,那可以把InstanceType<typeof Son>删掉,直接传入一个子组件方法的数据类型即可。

defineProps

vue3 setup中提供了defineProps的函数,普通写法的话,是没有类型提示的,也就是说写错了也不会报错。

我提供了两种写法,一种是泛型的写法,另一种是定义值的写法。

interface Form {
    age: number
    name:string
}

const props = defineProps<{
    msg: string
    form?: Form
}>()
复制代码
import { PropType } from 'vue'

defineProps({
    msg: {
        type: String,
        required: true,
    },
    form: {
        type: Object as PropType<Form>,
        required: false,
        default() {
            return {
                age: 99999,
            }
        },
    },
})
复制代码

这两种都能得到很好的代码提示,第一种比较简洁,但是不能设置默认值。第二种虽然繁琐,到但是可以设置默认值。我比较喜欢用第二种。

image.png

defineEmits

defineEmits也是同样的道理,不能得到很好的事件提示。

const emits = defineEmits<{
    (e: 'emits', data: number): void
    (e: 'ws', data: string): void
}>()

const emit = () => {
    emits('ws', '27')
}
复制代码

这样就能得到很好的代码提示 image.png

分类:
前端
收藏成功!
已添加到「」, 点击更改