目录
前言
一、定义
二、使用
1. 在 setup 中(推荐)
2. 非 setup 中
3. 对象写法的校验类型
4. 使用ts进行类型约束
5. 使用ts时props的默认值
三、注意事项
1. Prop 名字格式
2. 对象或数组类型的默认值
3. Boolean 类型转换
前言
Vue3相较于Vue2,Props传递的变化很大,并且结合ts后,写法有些怪异(choulou)。还有一些小细节,特此梳理一下。
一、定义
Vue3里组件之间属性传值需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute 。(关于透传attribute($attrs)在上文已讲,传送:Vue3中的透传Attributes / $attrs:简化组件开发的利器)
在Vue2中,可以简单的用数组或者对象的写法写出来就行,如下:
// 写法一
export default {
props: ['test'],
created() {
// props 会暴露到 `this` 上
console.log(this.test)
}
}
// 写法二
export default {
props: {
title: String,
likes: Number
}
}
但在Vue3中,就要区分是否使用 <script setup>
语法糖写法,还有是否使用ts。
二、使用
1. 在 setup 中(推荐)
注意:Vue3中只要是define开头的api,不需要从vue中引入。
<script setup>
// 数组写法
const props = defineProps(['test'])
console.log(props.tset)
// 对象写法并校验
defineProps({
title: String,
likes: Number
})
</script>
2. 非 setup 中
和Vue2保持一致
// 数组写法
export default {
props: ['test'],
setup(props) {
// setup() 接收 props 作为第一个参数
console.log(props.test)
}
}
// 对象写法
export default {
props: {
title: String,
likes: Number
}
}
3. 对象写法的校验类型
(来自Vue官网)
4. 使用ts进行类型约束
这个时候的写法可能就很不习惯了。
<script setup lang="ts">
defineProps<{
title?: string
likes?: number
}>()
</script>
拆分开来,其实等价于:
<script setup lang="ts">
interface Props {
title?: string
likes?: number
}
const props = defineProps<Props>()
</script>
5. 使用ts时props的默认值
当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。
如果是对象写法,可以约定默认值,但是使用刚才第4点的ts进行类型约束后,就做不到了。这个时候可以通过 withDefaults 来解决:
export interface Props {
msg?: string
labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
msg: 'hello',
labels: () => ['one', 'two']
})
相当于是将整个之前的defineProps作为参数传给了withDefaults。
三、注意事项
1. Prop 名字格式
如果一个 prop 的名字很长,应使用 camelCase 形式,因为它们是合法的 JavaScript 标识符,可以直接在模板的表达式中使用.
<script>
defineProps({
greetingMessage: String
})
</script>
<template>
<span>{{ greetingMessage }}</span>
</template>
2. 对象或数组类型的默认值
当使用对象写法来进行对props进行约束时,对象或数组类型是最特殊的,它们的默认值必须从一个工厂函数 defult 返回:
defineProps({
// 对象类型的默认值
propAOrO: {
type: Object,
// 工厂函数写法
default(rawProps) {
return { message: 'hello' }
}
},
})
3. Boolean 类型转换
为了更贴近原生 boolean attributes 的行为,声明为
Boolean
类型的 props 有特别的类型转换规则。
这个规则就像原生的带Boolean
类型的html标签,例如input标签type为radio的单选框标签。其中如果属性添加上disabled
,表示该单选框被禁用,无法进行选择。就等同于input里面对于disable属性默认为是true。
同理,当给组件声明为 Boolean
类型的 props ,也是这种规则。例如:
defineProps({
ischecked: Boolean
})
那这个组件也可以直接这么使用:
<!-- 等同于传入 :ischecked="true" -->
<SonCom ischecked />
<!-- 等同于传入 :ischecked="false" -->
<SonCom />