props \ defineProps
- 命名:如果一个 prop 的名字很长,建议使用小驼峰
props: { greetingMessage: String }
- 使用:
-
使用时为了和 HTML attribute 对齐,通常将其写为 短横线 形式
<MyComponent greeting-message="hello" />
-
有时虽为常量但也要使用 v-bind,因为这是一个 JavaScript 表达式而不是一个字符串
<BlogPost :likes="42" /> /* 42 为数字,不为字符串 */
<BlogPost :likes="false" /> /* false 为布尔值,不为字符串 */
<BlogPost is-published /> /* 仅写上 prop 但不传值,会隐式转换为 `true` */
如果没有在 props 中把 is-published 的类型设置为 Boolean,则这里的值为空字符串,而不是“true”。
- 只使用
v-bind
而非:prop-name
// data() 中定义
post: {
id: 1,
title: 'My Journey with Vue'
}
<BlogPost v-bind="post" />
// 等价于
<BlogPost :id="post.id" :title="post.title" />
- 单项数据流:父级 prop 的更新会向下流动到子组件中, 不应该在一个子组件内部改变 prop
1 props
一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute
<template>
中引用: propA<script>
中引用: this.propsA
// 1. 字符串数组
props: ['foo']
// 2. 对象
prop: {
title: String, // title 为名称,String 为构造函数
likes: Number
}
// 3. 可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
prop: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true,
},
// 带有默认值的数字
propD: {
type: Number,
default: 100,
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: "hello" };
},
},
propE: {
type: Object,
default: () => {}
},
propE: {
type: Array,
default() {
return [];
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ["success", "warning", "danger"].indexOf(value) !== -1;
},
},
}
- type 可以是原生构造器:String、Number、Boolean、Array、Object、Date、Function、Symbol
- type 也可以是一个自定义构造器,使用 instanceof 检测。
2 defineProps
只能在 <script setup>
中使用,无需导入
defineProps API 接收与 props 选项相同的值
<template>
中引用: propA<script>
中引用: props.propsA
// 仅<template> 中使用 propA、propB
defineProps({
propA: { type: [Number, String], default: '' },
propB: { type: Number, default: 2 }
});
// <script> 中也使用 propA、propB, 声明为变量
const props = defineProps({
propA: { type: [Number, String], default: '' },
propB: { type: Number, default: 2 }
});
- 因为 defineProps 只是一个语法糖,并不是一个真实存在的函数,它的作用在于告诉 vue 运行时工具,这里我们要引入一个变量。所以不能用普通变量的方式去看待它。
- 用于组件通信中父级组件给子级组件传值,其用来声明 props,其接收值为props选项相同的值
- 默认支持常见的类型检查,在 ts 下,我们需要明确变量的类型,类型经常是我们的自定义类型
- 只能在
<script setup>
中使用 - 不需要被导入即可使用,它会在编译
<script setup>
语法块时一同编译掉 - 必须在
<script setup>
的顶层使用,不可以在<script setup>
的局部变量中引用 - 不可以访问
<script setup>
中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中 - defineProps 是 props 从选项式 API 到组合式 API 的变体
理解 Vue3 里的 defineProps 和 defineEmits
vue3实战中关于 props 的一个细节问题
- 最初的 Composition API 是在 Options API 基础上改进的,不仅需要使用 setup() 函数,还要在 setup() 末尾返回所有模版需要用到的变量和函数,使用起来相当繁琐。于是后面就增加了
<script setup>
语法糖: - 从生命周期来讲,相当于 created
- 支持顶层 await(因为实际上这还是个 setup() 函数)
- 所有 import 的内容、声明的变量和函数默认都返回
- 至少省了两层缩进
- 但是由于少了 export,没法传参,也不方便暴露接口,所以作者就增加了三个工具方法:defineProps、defineEmits、defineExpose
- 注意,这三个工具方法只是帮助 Vue 编译器构建组件,它们不会出现在最终代码里,我们也不能预期它们会像普通函数那样工作。