Vue组件通信:父组件向子组件传递数据 & Props详解
在开始前,如果对子组件向父组件传值感兴趣的朋友可以阅读我的另一篇文章:
父组件向子组件传值常用props。页面的展示效果如下所示:
Props详解
props在子组件中定义,声明所接受的父组件传的值。即子组件告诉父组件:“我要接受这个数据哦,请你发给我”。
Props声明
prop需要在props
选项内声明,而prop声明可以采用数组、字符串和对象的形式。
- 以数组形式
如图所示,可以用一维数组的形式申明多个prop属性。但需要注意的是声明后需要通过this.propName
的方式使用。
2. 以字符串形式
字符串形式声明与数组形式声明相比,多了格式及其校验。(官方文档称作对象形式,但为了和方式3区分笔者暂且称其为字符串)
如果propaA传入字符串’test’,propB也传入字符串’111’,则代码会报错。如下图所示:
- 以对象形式
声明prop的对象主要有两个key值,分别为type
:prop的类型和default
:prop的默认值。当父组件未传值给子组件时,将显示default的值。
单向数据流
数据在props中是单向的,从父组件指向子组件。也就是说,子组件只能获取父组件的数据,不能进行修改。如果想要修改数据的话,需要在父组件中进行相关操作,否则会报错:
父组件修改数据后,子组件会自动更新。
Prop校验
从前面的prop声明可以看出,可以在声明的时候定义prop的type,type可选数字、字符串、对象、函数…并且,也能同时为一个prop定义多种type:propA: [String, Number]
(propA可以是字符串或数字)。
除此之外,还能通过validator()
的方式为prop自定义校验规则(官方文档的示例):
// 自定义类型校验函数
propF: {
validator(value) {
// value必须要包含数组中的其中一个值
return ['success', 'warning', 'danger'].includes(value)
}
}
静态 or 动态绑定prop
在父组件中,可以通过静态或动态的方式绑定prop。
- 静态绑定
例如propA="data from parent"
表示在父组件绑定了propA属性,并传入字符串’data from parent’作为打算发送给子组件的数据。 - 动态绑定
通过v-bind或":"可以动态地为父组件绑定prop值,例如:propA="propData"
动态为父组件绑定了propA,而propA的值则在data()
选项里定义。
父组件使用prop传值
- 子组件代码
<!-- 子组件 -->
<template>
<div class="childArea">
<div class="childTitle">This is child component</div>
<div class="content">
{{ displayContent }}
</div>
<el-button
type="warning"
size="small"
plain
@click="getMessage">
子组件中的按钮
</el-button>
</div>
</template>
<script>
export default {
props: ['musicName'], //子组件定义prop接受父组件的传值
data() {
return {
displayContent: '礼堂三部曲是?'
}
},
methods: {
getMessage() {
// 将父组件的传值赋值给展示内容
this.displayContent = this.musicName
}
}
}
</script>
<style lang="scss" scoped>
.childArea {
width: 200px;
height: 200px;
background-color: #fffef9;
border-radius: 20px ;
box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset,
rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;
.childTitle {
padding: 10px 0;
color: #fcaf17;
}
.content {
margin-bottom: 15px;
}
}
</style>
想让父组件传值给子组件,首先需要在子组件内声明prop属性来接受父组件值。因为prop会自动暴露在this上,因此通过this.musicName
进行赋值。
在子组件做好接受数据的准备后,就需要去父组件传值啦:
- 父组件代码
<!-- 父组件 -->
<!-- 父组件 -->
<template>
<div class="parentArea">
<div class="title">This is parent component</div>
<el-button
type="danger"
size="small"
plain>
父组件中的按钮
</el-button>
<!-- 3.父组件通过prop进行传值 -->
<ChildComponent class="child" music-name="zood、i got smoke、烟distance"/>
</div>
</template>
<script>
import ChildComponent from '@/views/test4.vue' //1.导入子组件
export default {
components: {
ChildComponent //2.定义子组件
}
}
</script>
<style lang="scss" scoped>
.parentArea {
background-color: #feeeed;
height: 400px;
.title {
font-size: 22px;
margin-bottom: 20px;
color: #f15b6c;
}
.child {
margin: auto;
margin-top: 30px;
}
}
</style>
父组件先要import引入子组件并注册,然后使用与子组件prop同名的属性传入参数。这里可能会有疑问:“子组件的prop明明是musicName,而父组件的prop却是music-name,骗…骗人的吧🥵” 。哈哈,这其实是vue的一个小小规范。
“虽然理论上你也可以在向子组件传递 props 时使用 camelCase 形式 (使用 DOM 模板时例外),但实际上为了和 HTML attribute 对齐,我们通常会将其写为 kebab-case 形式”
为父组件绑定prop时完全可以使用camelCase
形式,但按照规范建议选择kebal-case
形式。所谓kebab-case
,就是烤肉串式,即每个单词用“-”间隔,看上去像烤串一样。这里插播一下变量命名格式:
命名方式 | 中文名 | 示例 |
---|---|---|
camelCase | 小驼峰式 | appleAndBanana |
CamelCase | 大驼峰式 | AppleAndBanana |
snake_case | 小蛇式 | apple_and_banana |
SNAKE_CASE | 大蛇式 | APPLE_AND_BANANA |
keab-case | 烤肉串式 | app-and-banana |
最后我们点击子组件中的按钮,可以看到子组件成功获取父组件的传值:
在上面的示例中,笔者通过静态绑定prop的方式向子组件传值。除此之外,也可以采取动态绑定的方式传值。
<!-- 父组件 -->
<template>
<div class="parentArea">
<!-- v-bind/: 动态绑定music-name的值为message -->
<ChildComponent class="child" :music-name="message"/>
</div>
</template>
<script>
import ChildComponent from '@/views/test4.vue'
export default {
components: {
ChildComponent
},
data() {
return {
message: 'zood、i got smoke、烟distance'
}
}
}
</script>
如上方代码所示,在父组件中通过:music-name="message"
的方式将message值赋值给music-name属性,而父组件又将music-name赋值给子组件的musicName变量。
更多推荐
所有评论(0)