这次不讲基础,讲高阶。
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-a8ad28-1640855603194)]
defineEmits
defineEmits也是同样的道理,不能得到很好的事件提示。
const emits = defineEmits<{
(e: 'emits', data: number): void
(e: 'ws', data: string): void
}>()
const emit = () => {
emits('ws', '27')
}
复制代码
这样就能得到很好的代码提示
image.png点赞加关注,永远不迷路
网友评论