Vue如何实现组件间通信

1. 父子间通信

最常见的就是父子之间的通信,通信是双向的数据传递。

1.1 父组件 --> 儿子组件

父组件向儿子组件传递数据的方式就是 通过 Prop 向子组件传递数据。

//child.vue
<template>
    <div>
        我是儿子,我收到来自父亲的数据为 {{value}}
    </div>
</template>

<script>
export default {
    props:{
        value: String
    }
}
//App.vue
<template>
  <div id="app">
    <Child :value="x" />
  </div>
</template>

<script>
import Child from './components/Child'
export default {
  data(){
    return {
      x: 'hi,child'
    }
  },
  components:{
    Child
  }
}
</script>

1.2 儿子组件 --> 父组件

儿子组件向父组件传递数据的方式就是通过子组件内 $emit 触发自定义事件,子组件使用时 v-on 绑定监听自定义事件。

这里的 v-on 事件通信是在子组件使用时作为子组件的事件属性自动进行监听的。

因此儿子组件向父组件传递数据,依赖于子组件使用时的自定义事件属性。

//child.vue
<template>
    <div>
        我是儿子,我收到来自父亲的数据为 {{value}}
        <button @click="sayHi">
            向父组件打招呼
        </button>
    </div>
</template>

<script>
export default {
    props:{
        value: String
    },
    methods:{
        sayHi(){
            this.$emit('sayHi','hi,parent!');
        }
    }
}
</script>
//App.vue
<template>
  <div id="app">
    我是父组件,我收到子组件传来的数据为 {{y}}
    <Child :value="x" @sayHi="y = $event"/>
  </div>
</template>

<script>
import Child from './components/Child'
export default {
  data(){
    return {
      x: 'hi,child',
      y: ''
    }
  },
  components:{
    Child
  }
}
</script>

2. 爷孙间通信

爷孙间通信,可以使用两次 v-on 通信,爷爷爸爸通信,然后爸爸儿子通信。

也可使用下方的任意组件间通信的方式。

3. 任意组件间通信

任意组件间通信就不再区分是 A 向 B 通信,还是 B 向 A 通信,而是通用的方式,谁想发送数据就使用对应的 API 发送数据,谁想要接收什么数据,就使用对应的 API 接收。

任意组件间通信有两种方式,一种是使用 EventBus 发布订阅模式通信,一种是使用 Vuex 通信。

3.1 EventBus

EventBus ,从字面意思理解就是事件公交车,所有触发的事件传递的数据都从前门上车保存到公交车上,然后通过监听对应事件提供的出口让对应的事件数据下车。

EventBus,实际意思是发布和订阅模式,就是谁想把数据传递出去,就要通过触发自定义事件的 API 进行数据的发布;谁需要接收该数据信息的,就通过事件监听的 API 进行数据的监听,一旦检测到监听的数据发布出来,就会接收,这就是数据的订阅。

EventBus 通信方式最重要是搞明白发布和订阅的接口 API,在 Vue 中,Vue 实例有提供两个接口,即 $emit$on ,因此可以新创建一个空的 Vue 实例,来获得这两个接口。

const eventBus = new Vue();
eventBus.$emit(eventName, […args]) //发布事件
eventBus.$on(event, callback)      //订阅事件

实例如下:

// eventBus.js
import Vue from 'vue'
export const eventBus = new Vue();
//child
<template>
    <div>
        我是儿子,我收到来自父亲的数据为 <strong>{{value}}</strong>
        <button @click="sayHi">
            向父组件打招呼
        </button>
        <button @click="sibling">
            向兄弟组件打招呼
        </button>
    </div>
</template>

<script>
import {eventBus} from '../eventBus.js'
export default {
    props:{
        value: String
    },
    methods:{
        sayHi(){
            this.$emit('sayHi','hi,parent!');
        },
        sibling(){
            eventBus.$emit('sibling','hi,brother');
        }
    }
}
</script>

<style scoped>
    strong{
        color: red;
    }
</style>
//sibling
<template>
    <div>
        我是兄弟组件,我收到来自儿子组件的数据信息为 <strong>{{x}}</strong>
    </div>
</template>

<script>
import {eventBus} from '../eventBus.js'
export default {
    data(){
        return {
            x: ''
        }
    },
    mounted(){
        eventBus.$on('sibling', (msg)=>{
            this.x = msg;
        })
    }
}
</script>

<style scoped>
    strong{
            color: green;
    }
</style>
//parent
<template>
  <div id="app">
    我是父组件,我收到子组件传来的数据为 <strong>{{y}}</strong>
    <Child :value="x" @sayHi="y = $event"/>
    <Sibling></Sibling>
  </div>
</template>

<script>
import Child from './components/Child'
import Sibling from './components/Sibling'
export default {
  data(){
    return {
      x: 'hi,child',
      y: ''
    }
  },
  components:{
    Child,
    Sibling
  }
}
</script>

<style scoped>
    strong{
            color: blue;
    }
</style>

关于 EventBus 这部分,可能存在这样一个疑问,既然 Vue 实例中都有 $emit 和 $on,为什么不直接用 this.$emit 触发事件, this.$on 接收事件呢?还非得要额外一个空实例 eventBus = new Vue() 。那是因为,Vue 中每个组件都是一个单独的 Vue 实例,你在这个 Vue 实例中触发该实例的 emit 事件,另外一个实例的 on 事件是接收不到的,不在一辆公交车上,怎么能进行事件通信呢?因此就必须要一个公共的公交车,也就是事件总线。

上述实例中的 eventBus 的使用方法是局部的 eventBus,谁要用到 eventBus 要自己手动引入。也可以将 eventBus 做成全局的,比如挂在 vue 的原型上。

//main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

Vue.prototype.$eventBus = new Vue();//添加这句,一定要在下方的 new Vue 前。

new Vue({
  render: h => h(App),
}).$mount('#app')
//child
sibling(){
    this.$eventBus.$emit('sibling','hi,brother');
}
//sibling
mounted(){
    this.$eventBus.$on('sibling', (msg)=>{
        this.x = msg;
    })
}

除了上述的添加属性到 Vue 原型的方式外,还可以使用 Object.defineProperty() 为 Vue 原型添加属性。

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

let eventBus = new Vue()
Object.defineProperty(Vue.prototype,'$eventBus',{
  get(){
    return eventBus
  }
})

new Vue({
  render: h => h(App),
}).$mount('#app')

3.2 Vuex

Vue 组件间的通信也可使用专门为 vue.js 应用程序开发的状态管理模式:Vuex。Vuex 的使用比较复杂,详细可见 Vuex 博客。Vuex 适用于大型的复杂的 Vue 项目的状态管理。对于一些中小型的应用程序,可以根据 Vuex 的原理自定义 store 模式进行状态管理,vue 自定义状态管理,可详见 Vue 简单状态管理—store模式 博客。

无论是 Vuex 还是 自定义 store模式 ,其实现组件间通信的原理都是通过共享数据的方式实现的。组件间使用相同的数据源,当一个组件改变数据时,另一个组件依赖的数据源也就改变了。

以上就是Vue如何实现组件间通信的详细内容,更多关于Vue组件间通信的资料请关注我们其它相关文章!

(0)

相关推荐

  • 如何用Vue实现父子组件通信

    一.父子组件的关系构成 本篇文章将要总结的是Vue中父子组件之间的通信方式. 那在vue中父子组件之间的关系是怎么构成的呢,或者说哪个组件可以称为是父组件,哪个组件又可以称为是子组件呢. 在我的理解中,父子组件的关系构成也比较简单. 使用vue-cli工具构建的项目中,我们经常会在一个组件中注册引用另外一个组件. Home.vue <template> <div class="home"> <p>这里是Home组件</p> </di

  • vue element-ui table组件动态生成表头和数据并修改单元格格式 父子组件通信

    父组件 定义表头和表内容 data(){ return{ // 表格数据 tableColumns: [], // 表头数据 titleData:[], } } 引入并注册子组件 import TableComponents from "../../components/table/table"; //注册子组件table components: { tableC: TableComponents }, 获取表头和表内容数据.(真实数据应该是从接口获取的,由于是测试数据这里我先写死)

  • 详解利用eventemitter2实现Vue组件通信

    概述 当两个组件之间没有任何父子关系时,利用Vue标准的props传值和emit触发事件无法解决他们之间通信的问题.最近做的项目使用的是eventemitter2,来实现不相关组件之间的通信.这篇文章分享的是我对eventemitter2使用的总结和体会. eventemitter2的npm文档大家可以看eventemitter2介绍.它是node.js提供的事件接口.安装如下 npm install --save eventemitter2 模块的EventEmitter2属性是一个构造函数,

  • Vue组件通信的几种实现方法

    组件的通信 一般常见的组件之间的通信有以下几种情况,A和B,B和C,B和D之间都是父子关系,C和D之间是兄弟组件关系. 常用的通信手段有两种: 1.ref:给元素或组件注册引用信息 2.children:访问父级组件和子组件的实例. 这两种方式都是直接通过实例的方式获取的方式.示例如下: //comA组件A export default { data () { return { title: '测试通信' } }, methods: { sayHello () { window.alert('你

  • Vue.js组件通信之自定义事件详解

    组件通信 从父组件向子组件通信,通过props传递数据就可以了,但Vue组件通信的场景不止有这一种,归纳起来,组件之间的通信可以用下图来表示: 自定义事件 当子组件需要向父组件传递数据时,就要用到自定义事件.子组件用**$ emit()来触发事件**,父组件用**$ on()**来监听子组件的事件. 父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的事件. <!DOCTYPE html> <html lang="en"> <head>

  • Vue3使用mitt进行组件通信的步骤

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js. 比起Vue实例上的EventBus,mitt.js好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件的监听和批量移除,它还不依赖Vue实例,所以可以跨框架使用,React或者Vue,甚至jQuery项目都能使用同一套库. 1. 安装 推荐使用yarn安装(用过都知道有多丝滑) yarn add mitt 或者通过npm安装 npm install --save mitt 2. 引入到项目并挂载 可

  • vue中组件通信的八种方式(值得收藏!)

    前言 之前写了一篇关于vue面试总结的文章, 有不少网友提出组件之间通信方式还有很多, 这篇文章便是专门总结组件之间通信的 vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就好像过年回家,坐着一屋子的陌生人,相互之间怎么称呼,这时就需要先知道自己和他们之间是什么样的关系. vue组件中关系说明: 如上图所示, A与B.A与C.B与D.C与E组件之间

  • vue父子组件通信的高级用法示例

    前言 vue项目的一大亮点就是组件化.使用组件可以极大地提高项目中代码的复用率,减少代码量.但是使用组件最大的难点就是父子组件之间的通信. 子通信父 父组件 <template> <div class="parent"> 我是父组件 <!--父组件监听子组件触发的say方法,调用自己的parentSay方法--> <!--通过:msg将父组件的数据传递给子组件--> <children :msg="msg" @s

  • Vue组件通信中非父子组件传值知识点总结

    前言: 如果想要了解非父子关系的组件传值,最好是在了解父传子和子传父的基础上在来了解非父子传值可能会有更透彻的思路. 因为非父子传值是通过定义事件总线来代理实现父传子+子传父从而实现的传值方式. 这是我总结的父子传值相关的知识,可供参考:  https://www.jb51.net/article/121806.htm 然后大概回顾一下父子传值的过程: 根据上述信息可知,如果两个组件需要传递值那么需要这两个组件之间是父子关系才能传递数据. 那么如果有这样一个组件,既可以帮你传递数据,又可以帮你接

  • Vue如何实现组件间通信

    1. 父子间通信 最常见的就是父子之间的通信,通信是双向的数据传递. 1.1 父组件 --> 儿子组件 父组件向儿子组件传递数据的方式就是 通过 Prop 向子组件传递数据. //child.vue <template> <div> 我是儿子,我收到来自父亲的数据为 {{value}} </div> </template> <script> export default { props:{ value: String } } //App.v

  • vue之父子组件间通信实例讲解(props、$ref、$emit)

    组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.那么组件间如何通信,也就成为了vue中重点知识了.这篇文章将会通过props.$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信. 在说如何实现通信之前,我们先来建两个组件father.vue和child.vue作为示例的基础. //父组件 <template> <div> <h1>我是父组件!</h1> <child>

  • vue组件间通信子与父详解(二)

    接着vue组件父与子通信详解继续学习. 二.组件间通信(子组件传值给父组件) 通过事件的方式来完成数据的传输. ①在父组件中 定义一个方法,用来接收子组件所通过事件传来的值 methods:{ recvMsg:function(msg){ //参数msg就是子组件通过事件出来的数据 } } ②绑定事件处理函数 事件一般情况 都是自定义事件 <child-component @myEvent="recvMsg"></child-component> ③在子组件触发

  • vue组件间通信解析

    组件间通信(父子,兄弟) 相关链接\组件通信:点击查看 学习链接:Vue.js--60分钟快速入门点击查看 分分钟玩转Vue.js组件点击查看 父组件传子组件 父传子方法(一) 属性传递 props //子组件 <template> <ul> <li v-for="item in dataList">{{item}}</li> </ul> </template> <script> export defa

  • Vue 父子组件、组件间通信

    本人对Vue组件间通信不懂,搜索了很多关于Vue 父子组件间通信介绍,下面我来记录一下,有需要了解Vue 父子组件.组件间通信的朋友可参考.希望此文章对各位有所帮助. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件</title> <meta name="viewport"

  • vue组件间通信六种方式(总结篇)

    前言 组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.一般来说,组件可以有以下几种关系: 如上图所示,A 和 B.B 和 C.B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系(可能隔多代). 针对不同的使用场景,如何选择行之有效的通信方式?这是我们所要探讨的主题.本文总结了vue组件间通信的几种方式,如props. $emit / $on .vuex. $parent / $children . $attrs

  • Vue组件间通信 Vuex的用法解析

    上回说到Vue组件间通讯,最后留了一个彩蛋~~~Vuex.Vuex是另一种组件通讯的方法,这节来说说Vuex(store仓库). 首先Vuex需要安装,安装的方式有很多,在这里就不一一细说了.我是通过npm方式安装的: npm install vuex --save 安装好之后需要再main.js里全局引入: import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)new Vue({el:'#app',store,components

  • Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)

    前言 除了使用 Vuex 方法外,vue 提供了各种各样的组件间通信的方案.文章整理一下父子组件.兄弟组件.祖先后代组件间是如何通信的.

  • 超详细的vue组件间通信总结

    目录 前言 一.props.$emit单向数据流 二.$parent.$children 三.$attrs.$listeners 四.provide.inject 五.eventBus(事件总线) 六.vuex 七.localstorage 总结 前言 组件通信在我们平时开发过程中,特别是在vue和在react中,有着举足轻重的地位.本篇将总结在vue中,组件之间通信的几种方式: props.$emit $parent.$children $attrs.$listeners provide.in

  • Vue实现组件间通信的几种方式(多种场景)

    目录 1.Props 父 >>> 子  (Props) 子 >>> 父 ($emit) 2.Bus事件总线 3.Vuex状态管理库 4.Router 5.缓存 以下是我在开发中用到过的vue组件之间的通信方式,不同的场景使用不同的方式,基本满足所有开发场景中的通信需求,从最简单的事例着手,讲述如何使用,话不多说直接开始,满满的干货,建议看完. 1.Props 父 >>> 子  (Props) 一个组件里面引入另外一个组件,此时构成了一种"父子

随机推荐