什么是props
Props 是 Vue 组件之间通信的一种方式,通过 Props,父组件可以向子组件传递数据,即:父组件可以通过组件标签上的属性值把数据传递到子组件中。子组件可以根据自己的属性和方法去渲染展示数据或执行某些操作。由于 props 是单向数据流的,它是只能从父组件传递到子组件的,而子组件是无法更改 props 的值的,只能由父组件来修改。这样就保证了组件的数据传递不会出现混乱和错乱的情况。
如何定义props
在 Vue 组件中,需要通过配置 props 属性来定义组件的 props。在组件中添加 props 属性之后,就可以使用 props 选项接收从父组件传递的数据。
使用字符串数组方式定义props
Props可以是数组形式进行滴定仪,在这里Props定义了一个数组,其中每个元素都是一个字符串类型的Prop名,表示父组件可以向子组件传递的数据项。
没有使用 <script setup>
的组件中定义prop
使用字符串数组来声明 props非常简单,只需要在组件中进行如下定义即可:
代码语言:javascript复制 //在没有使用 `<script setup>` 的组件中定义prop
export default {
props: ['propA', 'propB', 'propC'],
setup(props) {
// setup() 接收 props 作为第一个参数
console.log(props.foo)
}
}
使用
在使用
代码语言:javascript复制<script setup>
import { defineProps } from 'vue'
const props = defineProps(['propA', 'propB', 'propC'])
console.log(props.foo)
</script>
使用对象的形式定义props
定义props,也可以通过对象形式声明,对于以对象形式声明中的每个属性,key 是 prop 的名称,而值则是该 prop 预期类型的构造函数。
没有使用 <script setup>
的组件中定义prop
代码语言:javascript复制// 非 <script setup>
export default {
props: {
// 确定props类型
propA: Number,
// 确定多个类型,其中可以设置默认值
propB: [String, Number],
// 自定义校验规则
propC: {
type: String,
required: true,
validator: function (value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
}
使用
代码语言:javascript复制// 使用 <script setup>
defineProps({
// 确定props类型
propA: Number,
// 确定多个类型,其中可以设置默认值
propB: [String, Number],
// 自定义校验规则
propC: {
type: String,
required: true,
validator: function (value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
})
定义成对象形式的Props更加灵活,可以设置数据类型、验证规则、默认值等属性。
如何使用props
在Vue3中,使用props需要进行以下几个步骤:
- 在组件选项中声明props:
props: {
propA: String,
propB: {
type: Number,
required: true
},
propC: {
type: [String, Number],
default: 'default value'
}
}
- 在组件的模板中使用props:
<template>
<div>
<p>Prop A: {{ propA }}</p>
<p>Prop B: {{ propB }}</p>
<p>Prop C: {{ propC }}</p>
</div>
</template>
- 在父组件中通过绑定属性的方式传入props:
<template>
<my-component prop-a="valueA" :prop-b="valueB"></my-component>
</template>
在以上代码中,“propA”、“propB”和“propC”是props的名称,“String”和“Number”是props的类型,“default value”是props的默认值,“valueA”和“valueB”是传入props的实际值。
props的使用场景
当我们需要在父组件和子组件之间进行数据传递时,就可以使用 Props。比如,在一个商品列表页面中,可以定义一个 ProductList
的父组件,子组件 ProductItem
可以通过 Props 接收父组件传递过来的产品信息,用于渲染商品列表。代码示例如下
- 在父组件
ProductList
中,定义一个产品列表,然后使用v-for
指令遍历产品列表,将每个产品作为一个子组件ProductItem
的product
props 传递给子组件:
<template>
<div>
<ProductItem v-for="product in products" :key="product.id" :product="product" />
</div>
</template>
<script>
import ProductItem from './ProductItem.vue'
export default {
components: {
ProductItem
},
data() {
return {
products: [
{
id: 1,
name: 'Product A',
price: 100,
description: 'This is product A'
},
{
id: 2,
name: 'Product B',
price: 200,
description: 'This is product B'
}
]
}
}
}
</script>
- 在子组件
ProductItem
中,通过props
对象声明一个名为product
的 props,然后通过模板插值,将父组件传递过来的产品信息进行渲染:
<template>
<div>
<h2>{{ product.name }}</h2>
<p>{{ product.description }}</p>
<p>Price: {{ product.price }}</p>
</div>
</template>
<script>
export default {
props: {
product: {
type: Object,
required: true
}
}
}
</script>
在上面的代码中,父组件 ProductList
将产品列表 products
传递给子组件 ProductItem
的 product
props,子组件 ProductItem
接收并渲染产品信息。这样可以很容易地实现在一个商品列表页面中渲染商品列表。
属性验证
前面提到过,在vue中可以通过定义 props
对象的方式进行Props校验。
为了校验一个属性,可以在 props
对象中添加一个与该属性名称相同的属性,该属性的值为一个对象。这个对象可以包含以下选项:
type
: 指定属性的类型。可以为 JavaScript 原生构造函数(如 String、Number、Boolean)或自定义构造函数。如果指定多个可选类型,可以使用数组[String, Number]
的方式表示。required
: 指定该属性是否是必需的。如果该属性没有默认值,并且父组件没有传递该属性,则会在控制台中打印警告。default
: 指定该属性的默认值。如果父组件没有传递该属性,则使用默认值。如果default
的值是对象或数组,必须将其设置为函数,并在函数中返回它,以避免值之间的共享。validator
: 指定一个自定义验证器函数,用于在接收到prop
的值时检查其有效性。
例如,下面的组件定义了一个名为 my-component
的组件,其中有一个 prop
名称为 age
,类型为 Number
,且必需:
<template>
<div>
<p>My age is: {{ age }}</p>
</div>
</template>
<script>
export default {
props: {
age: {
type: Number,
required: true
}
}
}
</script>
如果 my-component
在使用时没有传递 age
属性或 age
的值不是一个数字,则会在控制台中打印一个警告。如果正确设置了 prop
,则会将其传递给组件,并在模板中进行渲染。
除了上面提到的选项之外,还可以通过 props
对象的 .default
、.required
、.type
、.validator
属性来直接进行校验,例如:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: {
default: 'default message',
required: true,
type: String,
validator: (value) => {
return value.length <= 10
}
}
}
}
</script>
在这个例子中,message
属性的默认值是 default message
,必需且类型为 String
,并且在传递给子组件时使用 validator
函数进行验证。在这个例子中,验证器函数检查 message
是否超过 10 个字符,如果超过,将返回 false 并打印一个警告。
非 prop 特性
有时候父组件可能会传递一些特定于子组件的非 props 属性,非Prop特性指的是在组件中使用的但未在组件 props
中定义的属性。这些属性可以作为组件模板中的模板占位符或类名和样式绑定。例如传递 CSS 类名或事件监听器。在子组件内可以通过 $attrs
访问这些非 prop 特性。
- attrs: 包含了父作用域中不被认作 props 的特性绑定 (class 和 style 除外)。当一个组件被创建时,所有的特性 (除了已经在 prop 中定义的特性) 都会被自动添加到 child component 实例的 attrs 对象中。
比如在下面的代码中,定义了一个 MyComponent
组件,其中定义了两个 prop
(message
和 color
)和一个非 prop
特性 title
。这个组件使用 props
的值渲染了一个 <div>
元素,并将非 prop
特性绑定到该元素上:
<template>
<div :style="{ color }" :title="title">
{{ message }}
</div>
</template>
<script>
export default {
props: {
message: {
type: String
},
color: {
type: String,
default: 'black'
}
},
setup(props, { attrs }) {
// 获取非 prop 特性 title 的值
const title = attrs.title
return {
title
}
}
}
</script>
在上面的代码中,我们使用了 $attrs
对象来获取非 prop
特性 title
的值,并将其暴露给组件模板。例如,如果我们这样使用 MyComponent
组件:
<MyComponent message="Hello world" color="red" title="This is a title" />
则会在页面上渲染一个红色的 <div>
元素,并带有一个 title
特性。由于 title
不是一个 prop
,因此我们需要使用 $attrs
对象来获取它的值。
单向数据流特性
在 Vue 组件中,Props 是单向数据流的。这意味着,数据只能从父组件传递到子组件,而不能反向传递。这样的特性可以减少数据传递的混乱和错乱,也使得数据流动更加直观和易于维护。
在子组件中,不能直接更改由父组件传递过来的 Props 的值。如果需要更改 Props 的值,则应该使用事件等方式,比如通过 $emit
方法向父组件传递修改的信息,让父组件更改数据。
props的默认属性
Props 的默认特性就是用来处理默认值的。通常情况下,Props 接收的都是从父组件传递的数据,但是有时候如果父组件没有传递数据,则需要使用默认值。在定义 Props 时,可以使用 default
选项为 Props 指定默认值。
例如:
props: {
message: {
type: String,
default: 'Hello, Vue!'
}
}
在上面的代码中,对 Props message
设置了默认值为 Hello, Vue!
,如果在父组件没有传递 message
数据时,props message
的值就会是默认值 Hello, Vue!
。
此外,父组件也可以通过使用 v-bind
来动态地绑定 Props 的值。例如:
<template>
<example-component v-bind:message="dynamicMessage"></example-component>
</template>
<script>
export default {
data() {
return {
dynamicMessage: '动态绑定的消息'
}
}
}
</script>
在上面的代码中,dynamicMessage
是父组件中的数据,用它来动态绑定 Props 的值。在子组件中,可以使用 props.message
来访问父组件传递过来的数据。
好了,关于vue中的Props的详细介绍就到这里了,有疑问的小伙伴评论区留言。