props 数据 - 父组件向子组件单向传递数据 - vue 组件
props 数据
Props 声明
组件需要显式声明props,这样 Vue 才能知道,外部传入的,哪些是props,哪些是透传attribute(下一章中我们会讨论到它)。
在单文件组件中使用 在没有使用 请注意,传给defineProps()的参数和提供给props 选项的值是相同的,两种声明方式背后其实使用的都是 除了使用字符串数组来声明props外,还可以使用对象的形式: 对于以对象形式声明中的每个属性, 对象形式的 props 声明不仅可以一定程度上作为组件的文档,而且如果其他开发者在使用你的组件时传递了错误的类型,也会在浏览器控制台中抛出警告。 如果你正在搭配 TypeScript 使用 如果 prop 的名字很长,应使用camelCase形式,因为它们是合法的 JavaScript 标识符,可以直接在模板的表达式中引用。避免在作为属性 key 名时必须带引号。 从技术上来讲,你也可以在向子组件传递props时使用camelCase形式。(使用 DOM 模板时例外)而实际上为了和 HTML attribute 对齐,都会将其转为kebab-case形式: 一般情况下都会使用PascalCase作为组件标签名,因为这提高了模板的可读性,能很好地区分出 Vue 组件和原生 HTML 元素。然而这对于传递 props 来说收效却并不高,因此我们选择对其进行转换。 至此,你已经见过了很多像这样的静态值形式的 props: 相应地还有使用 在上述两个示例中,我们传入的值都是字符串类型的,但实际上任何类型的值都可以传给一个 prop。 如果你想要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的v-bind,而非 下面的模板: 所有的 prop 都遵循着单向下行绑定原则,prop 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改了父组件的状态,不然应用的数据流就会变得难以理解了 另外,每次父组件更新后,所有的子组件中的props都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告: 想要更改 prop 通常都符合以下两种场景: 1、prop 用来传递一个初始值;而子组件想在之后希望将其作为一个本地局部的数据来使用。在这种情况下,最好是新定义一个局部数据属性,从props上取初始值即可: 2、prop 以一种原始的值传入,但还需作转换。在这种情况中,最好是基于该 prop 值定义一个计算属性: 当对象或数组作为 prop 被传入时,虽然子组件无法更改 prop 绑定,但仍然可以更改对象或数组内部的值。这是因为 JavaScript 的对象和数组是按引用传递,而对 Vue 来说,禁止这样的改变。不虽然可能,但有很大的性能损耗,比较得不偿失。 这种更改的主要缺陷是它允许了子组件以某种不明显的方式影响了父组件的状态,可能会使数据流在将来变得更难以推理。在最佳实践中,你应该尽可能避免这样的更改,除非父子组件在设计上本来就需要紧密耦合。在大多数场景下,子组件应该抛出一个事件来通知父组件做出改变。 Vue 组件可以更细致地声明对传入的 props 的校验要求。比如我们上面已经看到过的类型声明,如果传入的值不满足类型要求,Vue 会在浏览器控制台中抛出警告来提醒使用者。这在开发给其他开发者使用的组件时非常有用。 要描述对 prop 的校验,你可以向 一些补充细节: 当 prop 的校验失败后,Vue 会抛出一个控制台警告(在开发模式下)。 如果使用了基于类型的 prop 声明,Vue 会尽最大努力在运行时按照 prop 的类型标注进行编译。举个例子, 此外, 你可以将其作为一个 prop 的类型: 这会校验 为了更贴近原生 该组件可以被这样使用: 当需要一个 prop 在声明时允许多种类型时,应该像这样: 无论声明类型的顺序如何,
props 选项
。key
是 prop 的名称,而值应该是预期类型的构造函数。比如,如果要求一个 prop 的值是number
类型,则可使用Number
构造函数作为其声明的值。props 传值
prop 名字格式
js
defineProps({
greetingMessage: String
})
template
{{ greetingMessage }}
template
静态 vs.动态 Props
v-bind
或缩写:
所动态绑定的 props 值:props 传值类型
Number
Boolean
Array
Object
传入一个对象的所有 property
:prop-name
。例如,对于一个给定的对象post
:post: {
id: 1,
title: 'My Journey with Vue'
}
等价于:
单向数据流
const props = defineProps(['foo'])
// ❌ 警告!prop 是只读的!
props.foo = 'bar'
const props = defineProps(['initialCounter'])
// 计数器只是将 props.initialCounter 作为初始值
// 像下面这样做就使 prop 和后续更新无关了
const counter = ref(props.initialCounter)
const props = defineProps(['size'])
// 该 prop 变更时计算属性也会自动更新
const normalizedSize = computed(() => props.size.trim().toLowerCase())
更改对象/数组类型的 prop
prop 校验
defineProps()
宏提供一个带有 prop 校验的对象,而不是一个字符串数组,例如:defineProps({
// 基础类型检查
// (给出 `null` 和 `undefined` 值则会跳过任何类型检查)
propA: Number,
// 多种可能的类型
propB: [String, Number],
// 必传,且为 String 类型
propC: {
type: String,
required: true
},
// Number 类型的默认值
propD: {
type: Number,
default: 100
},
// 对象类型的默认值
propE: {
type: Object,
// 一个返回默认 对象/数组值 的工厂函数
default() {
return { message: 'hello' }
}
},
// 自定义类型校验函数
propF: {
validator(value) {
// The value must match one of these strings
return ['success', 'warning', 'danger'].includes(value)
}
},
// 函数类型的默认值
propG: {
type: Function,
// 不像对象或数组的默认,这不是一个工厂函数。这会是一个用来作为默认值的函数
default() {
return 'Default function'
}
}
})
defineProps()
宏中的参数不可以访问中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。
required: true
。undefined
。default
值,那么在 prop 的值被解析为undefined
时,无论 prop 是未被传递还是显式指明的undefined
,都会改为default
值。defineProps
会被编译为{msg:{type: String, required: true}}
。类型检查
type
可以是下列原生构造函数中的一个:type
还可以是一个自定义的构造函数,并且通过instanceof
来检查、断言。例如下面这个类:class Person {
constructor(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
}
defineProps({
author: Person
})
author
prop 的值是否是由new Person
创建的。Boolean 类型转换
Boolean
attributes 的行为,声明为Boolean
类型的 props 有特别的类型转换规则。以带有如下声明的组件为例:
defineProps({
disabled: Boolean
})
defineProps({
disabled: [Boolean, Number]
})
Boolean
类型的特殊转换规则都会被应用。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!