Vue常见组件间通信方案及典型应用场景详解

目录
  • 什么是组件通信
    • 1、父子组件通信场景
    • 2、兄弟组件通信场景
    • 3、根组件和后代组件通信场景
    • 4、插槽通信场景
    • 5 无直接关系的组件通信场景
    • 6 大型项目中的复杂组件通信场景 - Vuex状态管理
    • 7 其他的一些组件通信方案
  • 总结

什么是组件通信

所谓组件通信,就是组件之间的数据交互,也就是把一个组件A里面的数据传递到另一个组件B,并能够让组件B根据这个数据更新界面。

在 Vue中,可用的通信方案有很多,下面给大家描述几个常用的组件通信方案及其典型的应用场景。

1、父子组件通信场景

父子组件通信是最典型的组件通信场景,没有之一,他们之间通信主要使用自定义属性或者ref。

第一种是自定义属性,使用较为广泛,在子组件中使用 props 选项进行接收,子组件向父组件回传数据,使用自定义事件,在子组件中使用 $emit() 方法触发执行,并回传数据给父组件。

  // 定义组件h1-box
  Vue.component("h1-box", {
    // 通过props设置自定义属性title接收组件外传值
    props: ["title"],
    // 通过emits设置自定义事件向外部发送事件
    emits: ['give'],
    methods:{
      clickHandler(){
        // 通过$emit() 方法触发执行把当前组件数据带出去
        this.$emit('give',{name:'lucy'})
      }
    },
    mounted() {
      // 通过this.title可以获取外部传入组件的值
      console.log(this.title);
    },
  });

第二种使用 ref 实现通信。我们知道,使用 ref 可以快速访问一个组件实例对象及其内部的数据和方法。这样的话,在父组件中借助 refs可以访问子级组件的数据,还可以借助refs 可以访问子级组件的数据,还可以借助 refs可以访问子级组件的数据,还可以借助refs 调用子级组件中的方法,并传递事件参数给子级组件。当然需要注意的是,在 Vue开发中,应该尽量减少对 ref 的使用。

<div id="app">
  <!-- 组件 -->
  <son ref="son"></son>
</div>
new Vue({
  el: "#app",
  mounted() {
    // 获取到组件实例,就可以任意操作组件实例
    console.log(this.$refs.son);
    let vm2 = this.$refs.son;
    // 修改son组件的响应式数据msg
    vm2.msg = "sz2111";
    // 调用son组件的changeMsg方法
    vm2.changeMsg("sz2116");
  },
  components: {
    // 定义组件son
    son: {
      data() {
        return {
          msg: "sz2114",
        };
      },
      methods: {
        changeMsg(val) {
          this.msg = val;
        },
      },
      template: `<h1>hello world</h1>`,
    },
  },
});

2、兄弟组件通信场景

这种场景使用状态提升,这个概念源自 React 中的状态提升思想。

所谓状态提升,就是当两个组件希望共享一个数据时,我们可以找到这两个组件最近的父级组件,把这个要被共享的变量定义在最近的父组件中去,再通过 props 向下传递给子组件们。需要注意的是,状态提升适合应用在简单的兄弟组件之间通信。当遇到较为复杂的组件关系时,使用状态提升就显得麻烦了。

上图图中如果想点击Font按钮改变主题字体大小,也就是Title和Font两个组件字体大小都改变。

如果Title和Font组件都维护自己组件的状态数据就不太好传递数据,就可以他他们的状态存储到共同的父组件状态中,也就是状态提升。

  <!-- 父组件app -->
  <div id="app">
    <!-- 子组件font -->
    <font :font="fontSize"></font>
    <!-- 子组件title -->
    <title :font="fontSize"></title>
  </div>
  // 父组件
  new Vue({
    el:'#app',
    data:{
      // 把子组件共同需要的数据存储在共同的父组件上
      fontSize:12
    }
  })
  // 子组件
  Vue.component('font',{
    // 通过自定义属性接受父组件传入的值
    props:['font'],
    template:`<div :style="{fontSize:font+'px'}">hello</div>`
  })
  // 子组件
  Vue.component('title',{
    // 通过自定义属性接受父组件传入的值
    props:['font'],
    template:`<div :style="{fontSize:font+'px'}">world</div>`
  })

3、根组件和后代组件通信场景

这种场景主要是provide/inject。使用 provide 选项,可以在任意组件中注入数据;使用 inject 选项,可以在后代组件中接受父级组件注入的数据。需要注意的是,provide/inject 这种通信方案是没有响应式的,即父组件注入的数据发生变化时,后代组件不会自动更新

上图在祖先组件通过provide传入的数据,在后代的所有组件中都可以通过inject获取到。

下面是一个通过provide/inject传值的例子

 <div id="app">
    <three></three>
  </div>
 // 根组件
  new Vue({
    el: "#app",
    // provide用于在一个vue实例里面给后面的子孙实例传递数据
    provide: function () {
      return {
        a: 100,
        c: 300,
        d: this.obj,
      };
    }
  });
  // 定义组件one
  Vue.component("one", {
    // inject用于在子孙组件中接收祖先通过provide传入的变量c
    inject: ["a"],
    template: `
      <div>
        <h1>我是one组件---{{a}}</h1>
      </div>
    `,
  });
  // 定义组件two,里面有子组件one
  Vue.component("two", {
    // inject用于在子孙组件中接收祖先通过provide传入的变量c,并重名成myC
    inject: {
      myC: "c",
    },
    template: `
      <div>
        <h1>我是two组件---{{myC}}</h1>
        <one></one>
      </div>
    `,
  });
  // 定义组件three,里面有子组件two
  Vue.component("three", {
    // inject用于在子孙组件中接收祖先通过provide传入的变量b,并重名成bbb,同时设置默认值299999
    inject: {
      bbb: {
        from: "b",
        default: 299999,
      },
    },
    template: `
      <div>
        <h1>我是three组件---{{bbb}}</h1>
        <two></two>
      </div>
    `,
  });

4、插槽通信场景

在封装组件时,可以为 组件添加自定义属性。使用这个组件时,在父级组件中使用 #slotName='scope' 指令可以接收到子组件插槽传递过来的数据。ElementUI 中的 Table 表格、VantUI 中的 Tabbar 组件,都用到了插槽通信。

  <div id="app">
    <child>
      <template #abc>
        <h1>sz2114</h1>
        <h2>sz2115</h2>
        <h3>sz2116</h3>
      </template>
      <template #cindy>
        <h1>sz2014</h1>
        <h2>sz2015</h2>
        <h3>sz2016</h3>
      </template>
    </child>
  </div>
  // 全局组件
  Vue.component("child", {
    template: `
        <div>
            <slot name='cindy'></slot>
            <h1>hello world</h1>
            <slot name='abc'></slot>
        </div>
    `,
  });
  let vm = new Vue({
    el: "#app",
  });

5 无直接关系的组件通信场景

在没有直接关联的组件之间通信可以使用事件总线。事件总线是一种基于订阅发布模式而设计的通信方案,在任意组件中订阅指定“频道”后,都能收到该“频道”上的消息

。事件总线,它的强大之处在于:它是一种“一对多”的通信方案,还是一种“多频道”的通信方案,非常强大。

    <div id="app">
      <input type="text" v-model="duanxin1" />
      <button @click="clickHandler">给老师发消息</button>
    </div>
      // 中央事件总线: 类似一个事件对象
      // 就像一个电信局
      var bus = new Vue();
      // 每个人就收短信都需要一个号码 (事件名)
      // 想要接收短信要先去电信办个卡 -- 注册一个号码
      bus.$on("cyrevent", function (data) {
        console.log("短信内容是");
        console.log(data);
      });
      new Vue({
        el: "#app",
        data() {
          return {
            duanxin1: "",
          };
        },
        methods: {
          clickHandler() {
            // 别人想给我发消息
            bus.$emit("cyrevent", this.duanxin1);
          },
        },
      });

6 大型项目中的复杂组件通信场景 - Vuex状态管理

Vuex状态管理是借助状态管理工具,可以实现任意组件之间的数据通信。Vuex 提供了 state、mutations 等接口,可以方便地实现任意未知关系的组件之间的数据交互。因此,我们经常称 Vuex是 Vue开发中的终极通信方案。终极的意思,不是说它可以随意地替代其它通信方案,而是说 Vuex很好用,能够清晰地管理数据流。

上图是vuex官方网站的工作流程图,特别形象。

7 其他的一些组件通信方案

上面说到的是比较常用的组件通信方式,还有一些方式是上面通信方法不能使用的替代手段。

第一个是: $parent/$children,借助这两个 API,可以实现在组件树之间任意穿梭。我们在当前组件的作用域中,可以访问到任意其它组件的内部数据,并调用它的方法。因此,这也是一种可用的通信方案。

第二个是:$attrs/$listeners。使用 $attrs 可以访问到父组件传递过来的自定义属性(除 class 和 style 外),使用 $listeners 可以访问并调用父组件传递过来的自定义事件,通过对自定义事件的调用还能向父组件回传数据。这两个内置 API,在某种程度上可以看成是父子组件通信的替代方案。

总结

虽然 Vue中可用的通信方案很多,但要注意的是“别滥用”。在同一个项目中,选择适合场景的通信方案很重要,不要使用过多的通信方式,这会导致代码很难维护。一个数据流不清晰的 Web应用,通常是很难得到持续发展的。

以上就是Vue常见组件间通信方案及典型应用场景详解的详细内容,更多关于Vue组件间通信应用场景的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue前端重构computed及watch组件通信等实用技巧整理

    目录 基于 springboot+vue 的测试平台开发 一.常规知识点 1.mounted 与 created 2. 计算属性 computed 3. 监视属性 watch 二.组件通信相关 1. 父组件给子组件传递 2. 子组件给父组件传值 3. 任意组件之间传值 4. vuex 基于 springboot+vue 的测试平台开发 继续更新 当前项目进度的前端重构已经完成了,在重构之余也对一些交互做了优化等.在本次的重构过程中感觉还是有不少收获,尤其是对于一些vue的前端知识的应用. 今天不

  • Vue组件通信方式(父传子、子传父、兄弟通信)

    目录 父组件传到子组件 子组件向父组件传值 非父子传参 (事件总线) vue 跨页面双向通信 同源通信 非同源通讯 父组件传到子组件 父组件是通过props属性给子组件通信的 数据是单向流动 父—>子 (子组件中修改props数据,是无效的,会有一个红色警告) 1. 父组件parent.vue代码如下:  <template>    <div class="parent">      <h2>{{ msg }}</h2>      

  • vue 组件通信的多种方式

    目录 前言 一.vuex 二.eventBus 三.props/emit 四.$parent/$children 五.$attrs/$listeners 六.provide/inject 前言 在vue中,​ 组件的关系不外乎以下三种: 组件是需要通信的,在开发中,常用到的通信方式有:vuex.eventBus.以及props与emit.$parent与$children,除此之外,还有provide与inject.$attrs与$listeners等. 一.vuex 这个相信大家用的很多了,简

  • Vue中父子组件通信与事件触发的深入讲解

    目录 一.组件 子组件 父组件 二.父子组件通信 父组件给子组件通信 子组件向父组件通信 三.父子组件事件触发 父组件调用子组件中的事件方法 子组件调用父组件中的事件方法 四.总结 一.组件 子组件 <template> <div style="border:1px solid black;width:400px; height: 130px;"> <h3>我是子组件</h3> <button>子组件将值传递给父组件</

  • Vue3.2+Ts组件之间通信的实现

    目录 父子组件通信 1.defineProps 2.defineEmits 3.defineExpose 4.v-model 兄弟组件通信 跨组件通信 Provide/Inject 受疫情影响,居家办公有一阵了,最近闲下来开始谈谈自己对于Vue3.2 + TS 知识的理解和使用.今天就总结下项目中常用到的一些组件之间的通信. vue框架提供了前端开发组件的思想,页面由一个个组件组合而成,在一些大型项目中,组件的数量越来越多,之间也需要通信,接下来我们进入主题,谈谈vue3.x + ts中如何使用

  • VUE中如何优雅实现爷孙组件的数据通信

    目录 $attrs和$listeners如何使用呢? $attrs的使用: $listeners的使用: 总结: 在开发的过程中遇到这么个场景,我需要在爷组件中请求数据,请求到的数据呢需要在孙组件中使用. 爷孙组件是这样的:我有一个根组件index.vue,根组件中有一个父亲组件<Father/>,在父亲组件中又有一个子组件,我们叫他孙组件<Son/> 看到这个场景,vuex.eventBus是有些大材小用了,然后我就用了props,将数据传递给<Father/>,又将

  • Vue常见组件间通信方案及典型应用场景详解

    目录 什么是组件通信 1.父子组件通信场景 2.兄弟组件通信场景 3.根组件和后代组件通信场景 4.插槽通信场景 5 无直接关系的组件通信场景 6 大型项目中的复杂组件通信场景 - Vuex状态管理 7 其他的一些组件通信方案 总结 什么是组件通信 所谓组件通信,就是组件之间的数据交互,也就是把一个组件A里面的数据传递到另一个组件B,并能够让组件B根据这个数据更新界面. 在 Vue中,可用的通信方案有很多,下面给大家描述几个常用的组件通信方案及其典型的应用场景. 1.父子组件通信场景 父子组件通

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

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

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

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

  • 详解Vue2中组件间通信的解决全方案

    前言 在Vue中组件是实现模块化开发的主要内容,而组件的通信更是vue数据驱动的灵魂,下面这篇文章将给大家介绍关于Vue2组件间通信的相关内容,下面话不多说,来一起看看详细的介绍. 组件通讯包括:父子组件间的通信和兄弟组件间的通信.在组件化系统构建中,组件间通信必不可少的. 父组件--> 子组件 1. 属性设置 父组件关键代码如下: <template> <Child :child-msg="msg"></Child> </templat

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

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

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

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

  • Vue如何实现组件间通信

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

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

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

  • 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

随机推荐