【入门级实例讲解上】Vue 2 父子组件通信

2,128 阅读2分钟

前言

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。众所周知,Vue 是一个轻量级的低门槛入门前端框架,其核心就是组件化开发,组件化贯穿了整个框架,并且各个组件实例的作用域都是相互独立的,这就以为这组件与组件之间的数据是无法相互通信的。但是真的是无法通信的吗?其实不然,在实际项目开发中,我们需要组件与组件之间互相传递数据,达到数据共享的目的,今天就来做一个总结。

基础入门

首先,我们先建两个组件,Farther.vueSon.vue 演示子组件是如何在父组件中被调用的,然后再展开如何通信问题。

  • Farther.vue
<template>
    <div class="fartherBox">
        <h2>我是父组件</h2>
        <son></son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Farther",
        components: {Son}
    }
</script>
  • Son.vue
<template>
    <div class="sonBox">
        <h3>我是子组件</h3>
    </div>
</template>

<script>
    export default {
        name: "Son"
    }
</script>

想必大家对这两段代码都很清楚明了,父组件通过 import 的方式引入子组件,并在 components 属性中声明注册,这样一来,子组件就可以使用标签的形式嵌入父组件了,实现了在父组件中调用子组件的效果:

效果演示.gif

父组件向子组件传值

props

  • 父组件以属性的方式传值给子组件

    <son message="莫西莫西" :dataFromFather="dataFromFather"></son>
    data() {
        return {
            dataFromFather: '我是父组件向子组件传递的值,使用 props 方式传值'
        }
    }
    
  • 子组件通过 props 方式接收数据

    props: {
        message: {
            type: String,
            default: '默认值'
        },
        dataFromFather: {
            type: String,
            default: '默认值'
        },
    }
    

    一种是静态传值,通过 v-bind 绑定 props 的自定义属性传递不是静态的字符串,它可以是一个表达式、布尔值、对象等等任何类型的值,是一种动态传值的方式。

效果演示

演示效果.gif

ref

  • 被用来给元素或子组件注册引用信息

    // Farther.vue
    <son ref="child"></son>
    mounted() {
        // 父组件 $refs 对象
        console.log("this.$refs", this.$refs);
        // 访问子组件实例
        console.log("this.$refs.child", this.$refs.child);
        // 通过调用子组件实例中的方法进行数据通信
        this.$refs.child.getDataFromFarther('使用 ref 向子组件传值');
    }
    
  • 引用信息将会注册在父组件的 $refs 对象上

    // Son.vue
    <h4 style="color: green">$ref 传值:{{ fartherData }}</h4>
    data() {
        return {
            fartherData: '默认值'
        }
    },
    methods: {
        getDataFromFarther(data) {
            this.fartherData = data;
        }
    }
    
  • $refs 是所有注册过的 ref 的一个集合

    image.png

    image.png

效果演示

效果演示.gif

小结

  • props 侧重于数据的传递,不能通过注册消息到父组件中获取子组件属性和方法。

  • $refs 非响应式,主要用来访问组件实例的,实现通信主要要调用子组件里的属性和方法。

  • ref 常用于 dom 元素上,作为一种选择器。

子组件向父组件传值

$emit

vm.$emit(event(自定义事件), arg(传递参数))
  • 父组件绑定子组件传递的 getDataFromSon 事件并定义 setDataFromSon() 方法将子组件传递过来的值赋值给当前父组件 dataOfSon 属性。注意:绑定的事件名要跟子组件中 $emit() 的事件名一致!!

    // 父组件
    <son @getDataFromSon="setDataFromSon"></son>
    data() {
        return {
            dataOfSon: '默认值'
        }
    },
    watch: {
        dataOfSon(newVal, oldVal) {
            console.log('监听旧值:', oldVal);
            console.log('现在新值:', newVal);
        }
    },
    methods: {
        setDataFromSon(data) {
            this.dataOfSon = data;
        }
    }
    
  • 子组件使用 $emit 绑定一个自定义事件 getDataFromSon ,父组件通过监听对应的事件拿到传递过来的参数 我是来自子组件的数据 ,从而实现子组件向父组件数据通信。

    // 子组件
    mounted() {
        this.$emit('getDataFromSon', '我是来自子组件的数据');
    }
    

效果演示

效果演示.gif

结尾

撰文不易,欢迎大家点赞、评论,你的关注、点赞是我坚持的不懈动力,感谢大家能够看到这里!Peace & Love。