Vue Props
在 Vue 中,父组件通过 Props 向子组件传递数据。Props 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
传递 Props
假设我们有一个博客文章组件 BlogPost.vue,我们希望从父组件 App.vue 向它传递文章的标题。
BlogPost.vue (子组件)
vue
<script setup>
// 使用 defineProps 宏来声明 props
const props = defineProps(['title'])
// props.title 可以在模板和脚本中访问
console.log(props.title)
</script>
<template>
<h4>{{ title }}</h4>
</template>App.vue (父组件)
vue
<script setup>
import BlogPost from './BlogPost.vue'
</script>
<template>
<BlogPost title="My journey with Vue" />
<BlogPost title="Blogging with Vue" />
<BlogPost title="Why Vue is so fun" />
</template>在这个例子中:
- 子组件
BlogPost.vue使用defineProps(['title'])宏来声明它接收一个名为title的 prop。 - 父组件
App.vue在使用<BlogPost>组件时,像传递 HTML attribute 一样,将一个字符串传递给titleprop。
Prop 命名规则
CamelCase vs. kebab-case: 在 JavaScript 中,prop 名称通常使用驼峰式 (camelCase),如
greetingText。但在 HTML attribute 中,推荐使用短横线分隔式 (kebab-case),如greeting-text。Vue 会自动处理这两种命名风格之间的转换。js// JS 中 defineProps(['greetingText'])html<!-- HTML 中 --> <MyComponent greeting-text="hello" />
动态 Props
类似于绑定普通的 HTML attribute,我们也可以使用 v-bind (或其简写 :) 来动态地传递 props。
vue
<script setup>
import { ref } from 'vue'
import BlogPost from './BlogPost.vue'
const posts = ref([
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
])
</script>
<template>
<BlogPost
v-for="post in posts"
:key="post.id"
:title="post.title"
/>
</template>Prop 校验
组件可以为 props 指定校验要求,例如类型检查。如果传入的值不满足要求,Vue 会在浏览器控制台中给出警告。
要指定校验,你可以向 defineProps 提供一个带有校验要求的对象,而不是一个字符串数组。
vue
<script setup>
defineProps({
// 基础的类型检查
// (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带默认值的数字
propD: {
type: Number,
default: 100
},
// 带默认值的对象
propE: {
type: Object,
// 对象或数组的默认值必须从一个工厂函数返回
default: () => ({ message: 'hello' })
},
// 自定义校验函数
propF: {
validator: (value) => {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].includes(value)
}
}
})
</script>单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在控制台给出警告。