在开始前,如果对子组件向父组件传值感兴趣的朋友可以阅读我的另一篇文章:

Vue组件通信:子组件向父组件传值(详解 & 代码示例)-- by 不关猫猫的事哦

父组件向子组件传值常用props。页面的展示效果如下所示:
在这里插入图片描述

Props详解

props在子组件中定义,声明所接受的父组件传的值。即子组件告诉父组件:“我要接受这个数据哦,请你发给我”。

Props声明

prop需要在props选项内声明,而prop声明可以采用数组、字符串和对象的形式。

  1. 以数组形式

在这里插入图片描述

如图所示,可以用一维数组的形式申明多个prop属性。但需要注意的是声明后需要通过this.propName的方式使用。
2. 以字符串形式

字符串形式声明与数组形式声明相比,多了格式及其校验。(官方文档称作对象形式,但为了和方式3区分笔者暂且称其为字符串)
在这里插入图片描述

如果propaA传入字符串’test’,propB也传入字符串’111’,则代码会报错。如下图所示:
在这里插入图片描述

  1. 以对象形式

声明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。

  1. 静态绑定
    例如propA="data from parent"表示在父组件绑定了propA属性,并传入字符串’data from parent’作为打算发送给子组件的数据。
  2. 动态绑定
    通过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变量。

GitHub 加速计划 / vu / vue
80
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐