在Vue中,组件之间数据传递可以使用props进行传递。

数据传递

示例1

App.vue

<template>
    <div>
        <Child :cData="childData"></Child>
    </div>
</template>
<script>
import Child from './Child.vue';
export default {
    components: {
        Child
    },
    data() {
        return {
            childData: {
                name: "Guo",
                age: 37,
                gender: 'M'
            }
        }
    }
}
</script>

Child.vue

<template>
    <div>
        Child components ---    
        {{ cData.name }}  - {{ cData.age }} -{{ cData.gender }}
    </div>
</template>
<script>
export default{
    props:['cData']
}
</script>

显示结果:

Vue3学习笔记:props 数据传递_props

在上述示例中,App.vue调用Child.vue中的组件Child,并将属性 cData传递给Child,同时Child.vue通过props进行接受,直接使用数组形式。

这种方式是最简单的形式。

数据校验

还可以通过一些属性对props中的数据进行校验,做常见的有 require default type 以及validator

以下为数据校验的示例:

示例2

App.vue

<template>
    <div>
        <button @click="handleShow">show/hide</button>
        <button @click="handleLevel">level+1</button>
        <Child :cData="childData" :dataShow="dataShow" :level="level"></Child>
    </div>
</template>
<script>
import Child from './Child.vue';
export default {
    components: {
        Child
    },
    data() {
        return {
            childData: {
                name: "Guo",
                age: 37,
                gender: 'M'
            },
            dataShow:true,
            level:0
        }
    },
    methods:{
        handleShow(){
            this.dataShow = !this.dataShow
        },
        handleLevel(){
            this.level++
        }
    }
}
</script>

Child.vue

<template>
    <div v-show="dataShow">
        Child components ---    
        {{ cData.name }}  - {{ cData.age }} - {{ cData.gender }} -{{ level }}
    </div>
</template>
<script>
export default{
    props:{
        cData:{
            type: Object
        },
        dataShow:{
            type: Boolean, 
            defualt: true
        },
        level:{
            type: Number,
            required: true,
            validator(value){
                return [0,1,2,3,4].includes(value)
            }
        }

    }
}
</script>

显示结果

Vue3学习笔记:props 数据传递_Vue_02

在这段代码中,父组件添加了两个按钮来改变传递给子组件的值dataShow level。在子组件中对props中的数据进行了一定的校验限制:cData类型为Object ;dataShow类型为Boolean,默认为true;level为必选,Number类型,数据限定在0,1,2,3,4

如图中所示,当点击level+1按钮,level不在属于0,1,2,3,4后控制台会有相应的报错。

数据流向

所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。

依旧以上文示例为例,

示例3

App.vue

<template>
    <div>
        <button @click="handleShow">show/hide</button>
        <button @click="handleLevel">level+1</button>
        <Child :cData="childData" :dataShow="dataShow" :level="level"></Child>
    </div>
</template>
<script>
import Child from './Child.vue';
export default {
    components: {
        Child
    },
    data() {
        return {
            childData: {
                name: "Guo",
                age: 37,
                gender: 'M'
            },
            dataShow:true,
            level:0
        }
    },
    methods:{
        handleShow(){
            this.dataShow = !this.dataShow
        },
        handleLevel(){
            this.level++
        }
    }
}
</script>

Child.vue

<template>
    <div v-show="dataShow">
        <button @click="handleLevel">level-1</button>

        Child components ---    
        {{ cData.name }}  - {{ cData.age }} - {{ cData.gender }} -{{ level }}
    </div>
</template>
<script>
export default{
    props:{
        cData:{
            type: Object
        },
        dataShow:{
            type: Boolean, 
            defualt: true
        },
        level:{
            type: Number,
            required: true,
            validator(value){
                return [0,1,2,3,4].includes(value)
            }
        }
    },
    methods:{
        handleLevel(){
            this.level++
        }
    }
}
</script>


Vue3学习笔记:props 数据传递_props_03

改动为在Child.vue中添加一个按钮,用来减少leve。可以看到控制台中直接有错误,不允许修改。


一些补充细节

  • 所有 prop 默认都是可选的,除非声明了 required: true。
  • 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined。
  • Boolean 类型的未传递 prop 将被转换为 false。这可以通过为它设置 default 来更改——例如:设置为 default: undefined 将与非布尔类型的 prop 的行为保持一致。
  • 如果声明了 default 值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的 undefined,都会改为 default 值。
  • 当 prop 的校验失败后,Vue 会抛出一个控制台警告 (在开发模式下)。
  • 如果使用了基于类型的 prop 声明 ,Vue 会尽最大努力在运行时按照 prop 的类型标注进行编译。举例来说,defineProps<{ msg: string }> 会被编译为 { msg: { type: String, required: true }}。