查看: 100|回复: 1

Vue父子组件通信实战:props、$ref和$emit用法详解

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
组件是 Vue.js 最强大的功能之一,但组件实例的作用域相互独立,不同组件之间无法直接引用数据。因此,实现父子组件间的通信成为 Vue 开发中的关键技能。本文通过 props、$ref 和 $emit 三个核心 API,结合实际代码示例,讲解父组件向子组件、子组件向父组件传递数据的几种方式。

在开始之前,先建立两个基础组件:father.vue 和 child.vue。
  1. <!-- 父组件 father.vue -->
  2. <template>
  3.   <div>
  4.     <h1>我是父组件!</h1>
  5.     <child></child>
  6.   </div>
  7. </template>
  8. <script>
  9. import Child from '../components/child.vue'
  10. export default {
  11.   components: { Child }
  12. }
  13. </script>
复制代码
  1. <!-- 子组件 child.vue -->
  2. <template>
  3.   <h3>我是子组件!</h3>
  4. </template>
  5. <script>
  6. export default {
  7. }
  8. </script>
复制代码

父组件通过 import 导入子组件,并在 components 中注册,随后即可在模板中以 <child> 标签的形式嵌入子组件。

一、通过 props 实现父传子

子组件的 props 选项用于接收父组件传递的数据。props 是单向绑定的:只能父组件向子组件传递,不可反向。传递方式分为静态传递和动态传递。

1. 静态传递

子组件在 export default 中声明 props 数组或对象,父组件在子组件标签上通过自定义属性传递静态字符串。
  1. <!-- 父组件 -->
  2. <template>
  3.   <div>
  4.     <h1>我是父组件!</h1>
  5.     <child message="我是子组件一!"></child>
  6.   </div>
  7. </template>
  8. <script>
  9. import Child from '../components/child.vue'
  10. export default {
  11.   components: { Child }
  12. }
  13. </script>
复制代码
  1. <!-- 子组件 -->
  2. <template>
  3.   <h3>{{ message }}</h3>
  4. </template>
  5. <script>
  6. export default {
  7.   props: ['message']
  8. }
  9. </script>
复制代码

2. 动态传递

多数场景需要传递动态数据(表达式、变量、布尔值、对象等)。使用 v-bind 将属性绑定到父组件的数据或 JavaScript 表达式。
  1. <!-- 父组件 -->
  2. <template>
  3.   <div>
  4.     <h1>我是父组件!</h1>
  5.     <child v-bind:message="a + b"></child>
  6.     <child v-bind:message="msg"></child>
  7.   </div>
  8. </template>
  9. <script>
  10. import Child from '../components/child.vue'
  11. export default {
  12.   components: { Child },
  13.   data() {
  14.     return {
  15.       a: '我是子组件二!',
  16.       b: 112233,
  17.       msg: '我是子组件三!' + Math.random()
  18.     }
  19.   }
  20. }
  21. </script>
复制代码

子组件接收方式与静态传递相同。

二、通过 $ref 实现父调用子方法和属性

ref 被用来给元素或子组件注册引用信息,引用信息会注册在父组件的 $refs 对象上。若 ref 用于子组件,则指向子组件实例,父组件可通过 this.$refs.refName 访问子组件中定义的属性和方法;若 ref 用于普通 DOM 元素,则指向该元素,作用类似 jQuery 选择器。

下面用 $ref 实现父组件向子组件传递数据(通过调用子组件方法):
  1. <!-- 父组件 -->
  2. <template>
  3.   <div>
  4.     <h1>我是父组件!</h1>
  5.     <child ref="msg"></child>
  6.   </div>
  7. </template>
  8. <script>
  9. import Child from '../components/child.vue'
  10. export default {
  11.   components: { Child },
  12.   mounted() {
  13.     console.log(this.$refs.msg);
  14.     this.$refs.msg.getMessage('我是子组件一!');
  15.   }
  16. }
  17. </script>
复制代码
  1. <!-- 子组件 -->
  2. <template>
  3.   <h3>{{ message }}</h3>
  4. </template>
  5. <script>
  6. export default {
  7.   data() {
  8.     return {
  9.       message: ''
  10.     }
  11.   },
  12.   methods: {
  13.     getMessage(m) {
  14.       this.message = m;
  15.     }
  16.   }
  17. }
  18. </script>
复制代码

在父组件 mounted 钩子中,通过 this.$refs.msg.getMessage('...') 调用子组件方法,将参数传入子组件。

props 与 $ref 的区别:
- props 侧重于数据传递,不能调用子组件的属性和方法,适合静态或动态数据绑定(如文章组件自定义标题和内容)。
- $ref 侧重于索引,主要用于调用子组件内部的属性和方法,不擅长数据传递。ref 在 DOM 元素上使用时,还能起到选择器的作用,该功能比作为组件索引更常用。

三、通过 $emit 实现子传父

$emit 用于子组件向父组件通信。语法:vm.$emit(event, arg) —— 绑定一个自定义事件 event,当执行该语句时,会将参数 arg 传递给父组件。父组件通过 @event 监听并接收参数。
  1. <!-- 父组件 -->
  2. <template>
  3.   <div>
  4.     <h1>{{ title }}</h1>
  5.     <child @getMessage="showMsg"></child>
  6.   </div>
  7. </template>
  8. <script>
  9. import Child from '../components/child.vue'
  10. export default {
  11.   components: { Child },
  12.   data() {
  13.     return {
  14.       title: ''
  15.     }
  16.   },
  17.   methods: {
  18.     showMsg(title) {
  19.       this.title = title;
  20.     }
  21.   }
  22. }
  23. </script>
复制代码
  1. <!-- 子组件 -->
  2. <template>
  3.   <h3>我是子组件!</h3>
  4. </template>
  5. <script>
  6. export default {
  7.   mounted() {
  8.     this.$emit('getMessage', '我是父组件!');
  9.   }
  10. }
  11. </script>
复制代码

子组件在 mounted 生命周期中触发 $emit,发出 'getMessage' 事件,并传递字符串。父组件监听该事件,触发 showMsg 方法,更新 title 数据。

以上就是 Vue 父子组件间三种主要通信方式的实践总结。掌握 props、$ref、$emit 的原理和使用场景,即可轻松应对大多数组件交互需求。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Vue父子组件通信实战:props、$ref和$emit用法详解

楼主写得很详细,props 和 $ref 的对比很清晰,尤其是实际场景选择的建议很实用。不过文章最后好像断在“ref 在 DOM”这里了?期待你把 $emit 的部分也补全,子组件向父组件通信这块也是面试常考的点。谢谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-12 21:02 , Processed in 0.026953 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部