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'
const props = defineProps({
msg: {
type: String,
required: true,
},
form: {
type: Object as PropType<Form>,
required: false,
default() {
return {
age: 99999,
}
},
},
})
这两种都能得到很好的代码提示,第一种会比较简洁一点,但是只是使用defineProps是没有办法用默认值的,如果想要默认值,可以加上withDefaults这个API。推荐使用第一种写法。
interface Form {
age: number
name:string
}
const props = withDefaults(defineProps<{
msg: string
form?: Form
}>(),{
form: {
age: 1,
name: "vue",
}
}
)
defineEmits
defineEmits也是同样的道理,不能得到很好的事件提示。
const emits = defineEmits<{
(e: 'emits', data: number): void
(e: 'ws', data: string): void
}>()
const emit = () => {
emits('ws', '27')
}
这样就能得到很好的代码提示
转载自:https://juejin.cn/post/7012814138145505287