一,前言
1.在vue2中,我们使用选项api中的props来接受父组件传递来的数据。
2.在vue3的setup中,我们使用defineProps来定义父组件传递的props
二,defineProps介绍
-
defineProps是vue3的一个宏函数,使用时可不导入
-
defineProps是一个函数,参数与vue2的props选项相同
defineProps({
msg:String,
name:{
type:String,
require:true,
default:'xxxx'
}
})
- 定义后props可直接在模板中使用,或者在setup其他地方使用
<template><span>{{ msg }}</span></template>
const props= defineProps({
msg:String,
name:{
type:String,
default:'xxxx'
}
})
console.log(props.name)
props.name = 123 //不能修改,声明的props的值是只读readonly的
- defineProps返回的props对象,是一个proxy对象,所有特性和reactive基本相同,只不过由defineProps定义出的props对象的值是只读的,还有在模板上可以单独属性直接使用
三,在typescript中为props添加标注类型
-
若不使用typescript来写可忽略,
-
当使用
defineProps({
msg:String,
name:{
type:String,
default:'xxxx'
}
})
- 更直接的方法是通过泛型参数来定义 props 的类型,注意当没有使用可选属性时,那么在使用该组件时,一定要传该属性,否则会报错
interface Props {
msg:string, //相当于require:true , 在使用该组件时一定要传改属性
name:string
age?:number //require:false
}
defineProps<Props>()
- 由于接口不能设置默认值,因此这种方式失去了设置默认值的能力,vue3提供了withDefaults 编译器宏解决
withDefaults(defineProps<Props>(), {
name: 'angle',
});
5.在使用withDefaults 编译器宏设置默认值时,对于引用类型,需要使用函数形式
withDefaults(defineProps<Props>(), {
list: ()=>[],
});
四,注意事项
-
defineProps只能在setup中使用,且只能在setup的顶层使用,不能在局部作用域使用
-
和vue2一样的原则,defineProps声明的props的值是只读readonly的,不能修改,也就是说,当传过来的是原始值时不能修改,当是对象类型时,不能修改对象类型的引用地址。
-
注意,在使用defineProps泛型参数来定义props时,泛型本身不能是外部引入的类型
import { Pl } from "../hook/index"; import { ref, reactive, toRefs, onMounted, defineProps } from 'vue' interface person { name: string, age: number } interface P { list?: [], person: person } const props = defineProps<Pl>(); //这样是不对的 const props = defineProps<P>(); //这样是正确的 -
在使用withDefaults 编译器宏设置默认值时,对于引用类型,需要使用函数形式
interface person { name: string, age: number } interface P { list?: number[], person: person } const props = withDefaults(defineProps<P>(), { list: () => { return [1, 2, 3] } }) //正确的 const props = withDefaults(defineProps<P>(), { list: [1,2,3] } //错误的