Vue组件间通信有哪些全面的方法和技巧?

2026-04-02 07:021阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3179个文字,预计阅读时间需要13分钟。

Vue组件间通信有哪些全面的方法和技巧?

目录+前言+组件介绍+一、父传子+1. 父组件通过props传递数据给子组件+2. 定义props的类型和默认值+二、子传父+子组件通过$emit传递数据给父组件+三、非父子组件间数据传递+1. 通过公共的事件总线传递数据

目录
  • 前言
  • 组件介绍
  • 一、父传子
    • 1. 父组件通过 props 传递数据给子组件
    • 2. 定义props的类型和默认值
  • 二、子传父
    • 子组件通过 $emit 传递数据给父组件
  • 三、非父子组件间数据传递
    • 1.通过公有的父组件进行非父子组件间的通信
    • 2. 通过使用一个空的 Vue 实例作为中央事件总线
  • 小结

    前言

    本章我们将介绍组件间是如何实现数据通信的。包括父组件向子组件、子组件向父组件、兄弟组件、非关系组件之间的数据通信。

    组件通信是组件式开发中非常重要的一部分,也是组件式开发中的难点。

    组件介绍

    组件是 vue 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。

    我们需要使用特定的方式来实现组件间的数据通信,接下来让我们一个个介绍这几种类别的组件通信是如何实现的。

    一、父传子

    1. 父组件通过 props 传递数据给子组件

    父组件通过 props 属性向子组件传递数据。

    子组件利用组件实例的 props 属性定义组件需要接收的参数,在使用组件时通过 attribute的方式传入参数。

    // 在子组件内定义组件接收一个参数 name {   props: ['name'] } // 父组件使用组件时传递参数 name <child :name="name"></child>

    接下来我们看一个具体示例:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<child :name="name"></child>', data() { return { name: '句号' } } }) Vue.component('child', { template: '<div>{{name}}</div>', props: ['name'] }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

    代码解释

    JS 代码第 14-18 行:定义了组件 child,并用 props 接收一个参数 name。

    JS 代码第 4-12 行:定义了组件 parent,在组件中使用 <child></child> 引用组件,并用 attribute 的方式将 name 传递给组件 child。

    在上面的例子中,组件 Child 接收参数 name,name 可以是字符串、数组、布尔值、对象等类型。但有时候我们需要给接收的参数指定一个特殊的类型和默认值,接下来我们就来介绍一下如何指定 props 的类型和默认值。

    Vue组件间通信有哪些全面的方法和技巧?

    2. 定义props的类型和默认值

    在上面的例子中,props 接收一个组件参数数组。

    实际上,props 也可以接收一个对象,对象key为组件接收参数的参数名,其值是一个对象,属性 type 用来指定参数的类型,属性 default 用来指定参数的默认值:

    { props: { name: { type: String, default: '句号' } } }

    接下来我们看一个具体示例:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<div><child :name="name" /> <child/></div>', data() { return { name: '慕课网' } } }) Vue.component('child', { template: '<div>{{name}}</div>', props: { name: { type: String, default: '句号' } } }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

    JS 代码第 11-19 行:定义了组件 child,并用 props 接收一个字符串类型的参数 name,其默认值是:句号。

    JS 代码第 3-10 行:定义了组件 parent,在组件中使用<child></child>两次引用组件,<child :name="name" /> 的方式传递 name 值,<child/> 使用默认的 name 值。

    TIPS: 注意,给数组和对象类型的 props设置默认值的时候,需要按照以下的写法:

    props: { detail: { type: Object, default: () => { return { name: '句号' } } }, loves: { type: Array, default: () => { return [] } } }

    二、子传父

    子组件通过 $emit 传递数据给父组件

    介绍完父组件传递数据给子组件的方式,我们再来看看子组件是如何传递数据给父组件的。

    子组件通过 $emit 传递事件给父组件,父组件通过$on监听事件:

    // 子组件定义事件 this.$emit('事件名称', '传递的参数') //例: this.$emit('add', 111) // 父组件监听事件的触发 <child  @事件名称="事件触发的方法"/>

    具体示例:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<div><child :name="name" :count="count" @add="add"/></div>', data() { return { name: '句号', count: 18 } }, methods: { // 父组件通过 @事件名 监听 // count 表示事件触发传递的参数 add(count) { this.count = count } } }) Vue.component('child', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。<button @click="add">加一岁</button></div>', props: { name: { type: String, default: '句号' }, count: { type: Number, default: 18 } }, methods: { add(){ // add -> 触发的事件名 // this.count + 1 -> 触发事件时传递的参数 this.$emit('add', this.count + 1) } } }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

    代码解释

    JS 代码第 19-38 行:定义了组件 child,该组件接收两个参数:1. 字符串类型的 name,默认值为:句号。2. 数字类型的 age,默认值为 18。组件模版中,通过按钮点击事件触发 add 方法,该方法内部通过$emit触发事件 add,并将 age + 1 的值作为参数传递。

    JS 代码第 3-18 行:定义了组件 parent,在组件中使用<child :name="name" :age="age" @add="add"/>引用组件,并绑定 add 事件,当事件 add 触发时调用 methods 中的 add 函数。

    三、非父子组件间数据传递

    前面我们介绍了具有父子关系的组件是如何进行数据传递的。但实际上,并不是所有的组件都是父子关系,组件间还有兄弟组件、子孙组件、无关系组件,那么这些组件间是如何进行通信的呢?

    相信在学完本章前面的内容之后这个问题并不能难倒大家。

    • 对于兄弟组件的数据通信:它们有共同的父组件,我们可以通过父组件传递的方式实现数据通信。
    • 对于子孙组件的数据通信:可以通过 props 的方式向下逐层传递下去,也可以通过 $emit 将事件向上逐层传递。
    • 对于非关系组件的数据通信:通过使用一个空的Vue实例作为中央事件总线。

    1.通过公有的父组件进行非父子组件间的通信

    假设现在有三个组件分别是<Parent>、<ChildA>、<ChildB>,其中组件<Parent>是<ChildA>和<ChildB>的父组件,<ChildA>和<ChildB>为兄弟组件,<ChildA>和<ChildB>组件间的通信可以借助<Parent>来间接传递。它的流程大致是这样:

    <ChildA>通过$emit将数据传递给<Parent>,<Parent>再通过props将数据传递给<ChildB> 。

    具体示例:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('person', { template: '<div><div>姓名:<input type="text" v-model="name"/></div><div>年龄:<input type="text" v-model="count"/></div><button @click="modify">修改</button></div>', data() { return { name: '句号', count: 18 } }, methods: { modify() { this.$emit('modify', {name: this.name, count: this.count}) } } }) Vue.component('detail', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。</div>', props: { name: { type: String, default: '句号' }, count: { type: Number, default: 18 } }, methods: { } }) var vm = new Vue({ el: '#app', data() { return { name: '句号', count: 18 } }, methods: { modify(detail) { this.name = detail.name this.count = parseInt(detail.count) } } }) </script> </html>

    代码解释

    JS 代码第 18-30 行:定义了组件 detail,它从父组件接收 name 和 age 两个参数。

    JS 代码第 3-17 行:定义了组件 person,它通过 $emit 将组件内输入的 name 和 age 传递给父组件。

    JS 代码第 38-41 行:接收了组件 person 传递过来的事件,并修改 name 和 age。

    HTML 代码第 3 行:将 name 和 age 传递给组件 detail。

    2. 通过使用一个空的 Vue 实例作为中央事件总线

    在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。

    首先我们需要做的是创建事件总线,并将它挂载到Vue原型上,在实例中通过this.bus.$emit发送事件,通过this.bus.$on接收事件

    // 定义事件总线 let bus = new Vue() Vue.prototype.bus = bus // 定义发送事件 this.bus.$emit('事件名称', data) // 定义接收事件 并在回调中接收参数 this.bus.$on('事件名称', (data) => { })

    接下来我们看一段具体示例代码:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> let bus = new Vue() Vue.prototype.bus = bus Vue.component('person', { template: '<div><div>姓名:<input type="text" v-model="name"/></div><div>年龄:<input type="text" v-model="count"/></div><button @click="modify">修改</button></div>', data() { return { name: '句号', count: 18 } }, methods: { modify() { this.bus.$emit('modify', {name: this.name, count: this.count}) } } }) Vue.component('detail', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。</div>', data() { return { name: '句号', count: 18 } }, mounted() { this.bus.$on('modify', (detail) => { this.name = detail.name this.count = detail.count }) } }) var vm = new Vue({ el: '#app', methods: { } }) </script> </html>

    代码解释

    JS 代码第 3-4 行:通过 new Vue() 创建一个 vue 实例,并将它挂载在 Vue 的原型上。这样,在 vue 组件中可以通过 this.bus 访问到这个实例对象。

    JS 代码第 5-18 行:定义了组件 person,当点击修改按钮的时候通过 this.bus.$emit 发送一个名为 modify 的事件,并将组件内输入的 name 和 age 作为参数传递。

    JS 代码第 19-33 行:定义组件 detail,在组件内部通过this.bus.$on监听名为 modify 的事件,当事件触发时执行修改操作。

    小结

    在本章,我们介绍了组件间的通信方式,主要有以下知识点:

    • 父组件通过 props 向子组件传递参数进行数据通信;
    • 子组件通过 $emit 向父组件传递事件进行数据通信;
    • 兄弟组件通过共同父组件进行数据通信;
    • 通过使用一个空的 Vue 实例作为中央事件总线进行非关系层组件的数据通信。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

    本文共计3179个文字,预计阅读时间需要13分钟。

    Vue组件间通信有哪些全面的方法和技巧?

    目录+前言+组件介绍+一、父传子+1. 父组件通过props传递数据给子组件+2. 定义props的类型和默认值+二、子传父+子组件通过$emit传递数据给父组件+三、非父子组件间数据传递+1. 通过公共的事件总线传递数据

    目录
    • 前言
    • 组件介绍
    • 一、父传子
      • 1. 父组件通过 props 传递数据给子组件
      • 2. 定义props的类型和默认值
    • 二、子传父
      • 子组件通过 $emit 传递数据给父组件
    • 三、非父子组件间数据传递
      • 1.通过公有的父组件进行非父子组件间的通信
      • 2. 通过使用一个空的 Vue 实例作为中央事件总线
    • 小结

      前言

      本章我们将介绍组件间是如何实现数据通信的。包括父组件向子组件、子组件向父组件、兄弟组件、非关系组件之间的数据通信。

      组件通信是组件式开发中非常重要的一部分,也是组件式开发中的难点。

      组件介绍

      组件是 vue 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。

      我们需要使用特定的方式来实现组件间的数据通信,接下来让我们一个个介绍这几种类别的组件通信是如何实现的。

      一、父传子

      1. 父组件通过 props 传递数据给子组件

      父组件通过 props 属性向子组件传递数据。

      子组件利用组件实例的 props 属性定义组件需要接收的参数,在使用组件时通过 attribute的方式传入参数。

      // 在子组件内定义组件接收一个参数 name {   props: ['name'] } // 父组件使用组件时传递参数 name <child :name="name"></child>

      接下来我们看一个具体示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<child :name="name"></child>', data() { return { name: '句号' } } }) Vue.component('child', { template: '<div>{{name}}</div>', props: ['name'] }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

      代码解释

      JS 代码第 14-18 行:定义了组件 child,并用 props 接收一个参数 name。

      JS 代码第 4-12 行:定义了组件 parent,在组件中使用 <child></child> 引用组件,并用 attribute 的方式将 name 传递给组件 child。

      在上面的例子中,组件 Child 接收参数 name,name 可以是字符串、数组、布尔值、对象等类型。但有时候我们需要给接收的参数指定一个特殊的类型和默认值,接下来我们就来介绍一下如何指定 props 的类型和默认值。

      Vue组件间通信有哪些全面的方法和技巧?

      2. 定义props的类型和默认值

      在上面的例子中,props 接收一个组件参数数组。

      实际上,props 也可以接收一个对象,对象key为组件接收参数的参数名,其值是一个对象,属性 type 用来指定参数的类型,属性 default 用来指定参数的默认值:

      { props: { name: { type: String, default: '句号' } } }

      接下来我们看一个具体示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<div><child :name="name" /> <child/></div>', data() { return { name: '慕课网' } } }) Vue.component('child', { template: '<div>{{name}}</div>', props: { name: { type: String, default: '句号' } } }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

      JS 代码第 11-19 行:定义了组件 child,并用 props 接收一个字符串类型的参数 name,其默认值是:句号。

      JS 代码第 3-10 行:定义了组件 parent,在组件中使用<child></child>两次引用组件,<child :name="name" /> 的方式传递 name 值,<child/> 使用默认的 name 值。

      TIPS: 注意,给数组和对象类型的 props设置默认值的时候,需要按照以下的写法:

      props: { detail: { type: Object, default: () => { return { name: '句号' } } }, loves: { type: Array, default: () => { return [] } } }

      二、子传父

      子组件通过 $emit 传递数据给父组件

      介绍完父组件传递数据给子组件的方式,我们再来看看子组件是如何传递数据给父组件的。

      子组件通过 $emit 传递事件给父组件,父组件通过$on监听事件:

      // 子组件定义事件 this.$emit('事件名称', '传递的参数') //例: this.$emit('add', 111) // 父组件监听事件的触发 <child  @事件名称="事件触发的方法"/>

      具体示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('parent', { template: '<div><child :name="name" :count="count" @add="add"/></div>', data() { return { name: '句号', count: 18 } }, methods: { // 父组件通过 @事件名 监听 // count 表示事件触发传递的参数 add(count) { this.count = count } } }) Vue.component('child', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。<button @click="add">加一岁</button></div>', props: { name: { type: String, default: '句号' }, count: { type: Number, default: 18 } }, methods: { add(){ // add -> 触发的事件名 // this.count + 1 -> 触发事件时传递的参数 this.$emit('add', this.count + 1) } } }) var vm = new Vue({ el: '#app', data() { return {} } }) </script> </html>

      代码解释

      JS 代码第 19-38 行:定义了组件 child,该组件接收两个参数:1. 字符串类型的 name,默认值为:句号。2. 数字类型的 age,默认值为 18。组件模版中,通过按钮点击事件触发 add 方法,该方法内部通过$emit触发事件 add,并将 age + 1 的值作为参数传递。

      JS 代码第 3-18 行:定义了组件 parent,在组件中使用<child :name="name" :age="age" @add="add"/>引用组件,并绑定 add 事件,当事件 add 触发时调用 methods 中的 add 函数。

      三、非父子组件间数据传递

      前面我们介绍了具有父子关系的组件是如何进行数据传递的。但实际上,并不是所有的组件都是父子关系,组件间还有兄弟组件、子孙组件、无关系组件,那么这些组件间是如何进行通信的呢?

      相信在学完本章前面的内容之后这个问题并不能难倒大家。

      • 对于兄弟组件的数据通信:它们有共同的父组件,我们可以通过父组件传递的方式实现数据通信。
      • 对于子孙组件的数据通信:可以通过 props 的方式向下逐层传递下去,也可以通过 $emit 将事件向上逐层传递。
      • 对于非关系组件的数据通信:通过使用一个空的Vue实例作为中央事件总线。

      1.通过公有的父组件进行非父子组件间的通信

      假设现在有三个组件分别是<Parent>、<ChildA>、<ChildB>,其中组件<Parent>是<ChildA>和<ChildB>的父组件,<ChildA>和<ChildB>为兄弟组件,<ChildA>和<ChildB>组件间的通信可以借助<Parent>来间接传递。它的流程大致是这样:

      <ChildA>通过$emit将数据传递给<Parent>,<Parent>再通过props将数据传递给<ChildB> 。

      具体示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('person', { template: '<div><div>姓名:<input type="text" v-model="name"/></div><div>年龄:<input type="text" v-model="count"/></div><button @click="modify">修改</button></div>', data() { return { name: '句号', count: 18 } }, methods: { modify() { this.$emit('modify', {name: this.name, count: this.count}) } } }) Vue.component('detail', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。</div>', props: { name: { type: String, default: '句号' }, count: { type: Number, default: 18 } }, methods: { } }) var vm = new Vue({ el: '#app', data() { return { name: '句号', count: 18 } }, methods: { modify(detail) { this.name = detail.name this.count = parseInt(detail.count) } } }) </script> </html>

      代码解释

      JS 代码第 18-30 行:定义了组件 detail,它从父组件接收 name 和 age 两个参数。

      JS 代码第 3-17 行:定义了组件 person,它通过 $emit 将组件内输入的 name 和 age 传递给父组件。

      JS 代码第 38-41 行:接收了组件 person 传递过来的事件,并修改 name 和 age。

      HTML 代码第 3 行:将 name 和 age 传递给组件 detail。

      2. 通过使用一个空的 Vue 实例作为中央事件总线

      在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。

      首先我们需要做的是创建事件总线,并将它挂载到Vue原型上,在实例中通过this.bus.$emit发送事件,通过this.bus.$on接收事件

      // 定义事件总线 let bus = new Vue() Vue.prototype.bus = bus // 定义发送事件 this.bus.$emit('事件名称', data) // 定义接收事件 并在回调中接收参数 this.bus.$on('事件名称', (data) => { })

      接下来我们看一段具体示例代码:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> let bus = new Vue() Vue.prototype.bus = bus Vue.component('person', { template: '<div><div>姓名:<input type="text" v-model="name"/></div><div>年龄:<input type="text" v-model="count"/></div><button @click="modify">修改</button></div>', data() { return { name: '句号', count: 18 } }, methods: { modify() { this.bus.$emit('modify', {name: this.name, count: this.count}) } } }) Vue.component('detail', { template: '<div>我是:{{name}}, 我今年 {{count}}岁。</div>', data() { return { name: '句号', count: 18 } }, mounted() { this.bus.$on('modify', (detail) => { this.name = detail.name this.count = detail.count }) } }) var vm = new Vue({ el: '#app', methods: { } }) </script> </html>

      代码解释

      JS 代码第 3-4 行:通过 new Vue() 创建一个 vue 实例,并将它挂载在 Vue 的原型上。这样,在 vue 组件中可以通过 this.bus 访问到这个实例对象。

      JS 代码第 5-18 行:定义了组件 person,当点击修改按钮的时候通过 this.bus.$emit 发送一个名为 modify 的事件,并将组件内输入的 name 和 age 作为参数传递。

      JS 代码第 19-33 行:定义组件 detail,在组件内部通过this.bus.$on监听名为 modify 的事件,当事件触发时执行修改操作。

      小结

      在本章,我们介绍了组件间的通信方式,主要有以下知识点:

      • 父组件通过 props 向子组件传递参数进行数据通信;
      • 子组件通过 $emit 向父组件传递事件进行数据通信;
      • 兄弟组件通过共同父组件进行数据通信;
      • 通过使用一个空的 Vue 实例作为中央事件总线进行非关系层组件的数据通信。

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。