Prop简介
- Prop 是子组件用来接受父组件传递过来的数据的一个自定义属性,一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
- 父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”:
1 2 3 4 5 6 7 8 9 10
| props: { propName1: propType1, propName2: { type: propType2, default: propDefaultValue, required: propRequired, validator: propValidator }, }
|
下面是对上述格式中各个选项的解释:
propName1
, propName2
, …:属性名称,用于接收从父组件传递的数据。
propType1
, propType2
, …:属性的类型,可以是以下之一:
- String
- Number
- Boolean
- Object
- Array
- Function
- Symbol
- 自定义构造函数(通常是自定义对象的构造函数)
default
(可选):指定属性的默认值。如果父组件没有传递该属性,将使用默认值。
required
(可选):如果设置为 true
,则表示该属性是必需的,父组件必须传递该属性。如果未传递,Vue 会发出警告。
validator
(可选):一个自定义验证函数,用于验证属性的值是否有效。该函数应返回 true
或 false
。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| props: { propA: String, propB: Number, propC: { type: Boolean, default: false }, propD: { type: Array, required: true }, propE: { type: Object, validator: function(value) { return value && typeof value === 'object' && 'name' in value; } } }
|
这样的 props
声明允许子组件接收来自父组件的数据,并对数据进行类型验证、默认值设置以及自定义验证。
prop使用案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - prop</title> <script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script> </head> <body> <div id="app"> <sutune city="长沙"></sutune> <sutune city="上海"></sutune> <sutune city="北京"></sutune> </div> <script> const app=Vue.createApp({}) app.component('sutune',{ props:['city'], template:'<h1>{{city}}</h1>' } )
app.mount('#app') </script> </body> </html>
|
代码的解释:
- 在HTML中,有一个具有
id
为 “app” 的 div
元素,它将用于挂载Vue应用。
- 在Vue应用的JavaScript部分,首先通过
Vue.createApp({})
创建了一个Vue应用实例。
- 使用
app.component
方法注册了一个全局组件,该组件名为 “sutune”。这个全局组件接受一个名为 “city” 的 props
属性,用于接收从父组件传递的城市名称。这里 city
是一个单一的属性,没有指定特定的类型。因此,Vue 3 不会强制检查传递给 city 的值的类型,而会接受任何类型的值。
- 在组件的模板中,使用
{{ city }}
插值将城市名称显示在 <h1>
元素中。
- 最后,使用
app.mount('#app')
将Vue应用实例挂载到具有 id
为 “app” 的HTML元素上。
- 在HTML中,我们使用了三次 “sutune” 组件,并为每个组件传递了不同的城市名称,分别是 “长沙”、”上海” 和 “北京”。每个 “sutune” 组件都会接收到相应的城市名称,并在其模板中显示出来。
动态prop
类似于用v-bind
绑定 HTML 特性到一个表达式,也可以用v-bind
动态绑定 props
的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
下面这个示例演示了如何在 Vue 3 中创建和使用全局组件,以及如何在父组件中使用 v-for
循环来动态渲染多个子组件,并通过 props
将数据传递给子组件,实现了城市信息的动态展示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 动态prop</title> <script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script> </head> <body> <div id="app"> <sutune v-for="site in sites" :id="site.id" :title="site.title"></sutune> </div> <script> const Site={ data(){ return { sites: [ {id:1,'title':'武汉'}, {id:2,'title':'长沙'}, {id:3,'title':'深圳'} ] } } }
const app=Vue.createApp(Site) app.component('sutune',{ props: ['id','title'], template: `<h4>{{id}}-{{title}}</h4>` } ) app.mount('#app') </script> </body> </html>
|
这段代码演示了如何在 Vue 3 中创建一个简单的应用,其中包括一个父组件(site
)和一个子组件(sutune
)。在父组件中,使用 v-for
指令动态地渲染多个子组件,并通过 props
将数据传递给子组件以渲染不同的内容。以下是代码的解释:
- 在 HTML 部分,有一个具有
id
为 “app” 的 div
元素,它将用于挂载 Vue 应用。
- 在 Vue 应用的 JavaScript 部分,首先创建了一个
site
对象。在 data
选项中,定义了一个名为 sites
的数组,其中包含了三个对象,每个对象都有 id
和 title
属性,代表了不同城市的信息。
- 使用
Vue.createApp(site)
创建了一个 Vue 应用实例,并将其赋给 app
变量。
- 使用
app.component
方法注册了一个全局组件,该组件名为 “sutune”。这个组件接受两个 props
属性,分别是 id
和 title
,用于接收从父组件传递的城市信息。
- 在组件的模板中,使用
{{ id }}
和 {{ title }}
插值将城市的 id
和 title
属性显示在 <h4>
元素中。
- 在父组件中,使用
v-for
循环遍历 sites
数组,并为每个数组元素创建一个 “sutune” 子组件。这样,每个子组件都会接收到不同的城市信息,并在页面上显示出来。
prop验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue Prop Validator 示例</title> <script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script> </head> <body> <div id="app"> <my-component :number="6"></my-component> </div>
<script> const app = Vue.createApp({}); app.component('my-component', { props: { number: { type: Number, validator(value) { return value % 2 === 0; } } }, template: ` <div> <p v-if="numberIsValid">偶数: {{ number }}</p> <p v-else>不是偶数: {{ number }}</p> </div> `, computed: { numberIsValid() { return this.number % 2 === 0; } } });
app.mount('#app'); </script> </body> </html>
|
defineProps
defineProps
是 Vue 3 Composition API 中的一个函数,用于在一个组件中定义可接收的 props。在函数式组件和setup
函数内部使用它。
- 在
<script setup>
中必须使用 defineProps API 来声明 props ,它们具备完整的类型推断并且在 <script setup>
中是直接可用的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <h1>name:{{ name }}</h1> <p>age:{{ age }}</p> </div> </template> <script setup> import { defineProps } from 'vue';
const props = defineProps({ name: String, age: { type:Number, default:20 }, });
</script>
|
在父组件中直接传值如下
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <div> <Child :name="parentname" :age="parentage" /> </div> </template> <script setup> import Child from './Child.vue'; const parentname = 'sutune'; const parentage = 32; </script>
|
参考资料