Vue3 Props
Prop 类型
以字符串数组形式列出的 prop:
1 | props: ['title', 'likes', 'isPublished', 'commentIds', 'author'] |
可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:
1 | props: { |
这不仅为你的组件提供了文档,还会在它们遇到错误的类型时从浏览器的 JavaScript 控制台提示用户。
More:类型检查和其它 prop 验证
传递静态或动态的 Prop
给 prop 传入一个静态的值:
1 | <blog-post title="My journey with Vue"></blog-post> |
通过 v-bind
或简写 :
动态赋值:
1 | <!-- 动态赋予一个变量的值 --> |
传入一个数字
1 | <!-- 即便 `42` 是静态的,我们仍需通过 `v-bind` 来告诉 Vue --> |
传入一个布尔值
1 | <!-- 包含该 prop 没有值的情况在内,都意味着 `true`。 --> |
传入一个数组
1 | <!-- 即便数组是静态的,我们仍需通过 `v-bind` 来告诉 Vue --> |
传入一个对象
1 | <!-- 即便对象是静态的,我们仍需通过 `v-bind` 来告诉 Vue --> |
传入一个对象的所有 property
使用不带参数的 v-bind
1 | post: { |
1 | <blog-post v-bind="post"></blog-post> |
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外变更父级组件的状态,从而避免你的应用的数据流向难以理解。
每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。
两种常见的试图变更一个 prop 的情形:
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用:
解决方法:定义一个本地的 data property 并将这个 prop 作为其初始值
1 | props: ['initialCounter'], |
这个 prop 以一种原始的值传入且需要进行转换:
解决方法:使用这个 prop 的值来定义一个计算属性
1 | props: ['size'], |
TIP
在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态,且 Vue 无法为此向你发出警告。
作为一个通用规则,应该避免修改任何 prop,包括对象和数组,因为这种做法无视了单向数据绑定,且可能会导致意料之外的结果。
Prop 验证
我们可以为组件的 prop 指定验证要求,前提是你知道的这些类型。
这在开发一个会被别人用到的组件时尤其有帮助。
1 | app.component('my-component', { |
当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
类型检查
type
可以是下列原生构造函数中的一个:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
此外,type
还可以是一个自定义的构造函数,并且通过 instanceof
来进行检查确认。
Prop 的大小写命名 (camelCase vs kebab-case)
HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。
这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名。
1 | const app = Vue.createApp({}) |
1 | <!-- 在 HTML 中使用 kebab-case --> |