资讯专栏INFORMATION COLUMN

vue组件通信的几种方式

vspiders / 2003人阅读

摘要:虽然和都可以获取组件实例,但是它们无法在跨级或兄弟间通信,这是它们的缺点。也就是在父组件中提供一个值,并且在需要使用的子孙组件中注入改值,即不仅仅是,只要是的子组件,无论隔多少代,都可以通过这个的方式注入。通过混入组件,实现组件间的通信。

写在前面

vue 的组件化应该是其最核心的思想了,无论是一个大的页面还是一个小的按钮,都可以被称之为组件。基于 Vue 的开发,就是在写一个个组件,无论是基础组件还是业务组件,最后都是要拼装在一起。按照组件的层级关系,可以把组件之间的关系归纳为:父子关系、隔代关系、兄弟关系,无关联关系。

$ref$parent$children

基于当前上下文的,可以通过 $ref$parent$children 访问组件实例,可以直接调用组件的方法或访问数据。其中 $parent 可以访问当前组件的父组件,$children 可以访问当前组件的所有子组件。虽然 $parent$children 都可以获取组件实例,但是它们无法在跨级或兄弟间通信,这是它们的缺点。

provideinject

provide / inject 是 Vue 在 2.2.0 版本后新增的 API。

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

也就是在父组件中提供一个值,并且在需要使用的子孙组件中注入改值,即:

// Parent.vue
export default {
    provide() {
        return {
            name: "Stone"
        }
    }
}
// Child.vue
export default {
   inject: ["name"],
   mounted() {
       console.log(this.name)
   }
}

不仅仅是 Child.vue ,只要是 Parent.vue 的子组件,无论隔多少代,都可以通过这个的方式注入。 这种多级组件透传的方式可以保证单向数据流的清晰性,例如像用户信息这样的全局信息,就可以借助这两个 API 来完成,而没有引入第三方库 vuex

替代 Vuex

vuex 是把数据集中管理,然后哪里需要就在哪里获取,按照这个思路,我们可以在根组件 App.vue 中注入全局信息,并且在页面的任何地方使用。

// App.vue

export default {
    provide() {
        return {
            userInfo: this.user
        }
    },
    data() {
        return {
            user: {}
        }
    },
    methods: {
      getUserInfo () {
        $.ajax("/user/info", (data) => {
          this.user = data
        })
      }
    }
}

把整个 App.vue 的实例 this 对外提供, 这样其他页面就可以通过 this.userInfo 来获取用户信息。


$attrs$listeners
这两个 API 是 Vue 2.4.0 新增的。$attrs ,继承所有的父组件属性;$listeners ,它是一个对象,里面包含了作用在这个组件上的所有监听器。

主要用途就是用在父组件传递数据给子组件或者孙组件。








dispatchbroadcast

这两个 API 是 Vue 1.0 版本的,$dispatch 用于向上级派发事件,$broadcast 用于向下级广播事件的,它们在 2.0 版本中已经被废弃了。

因为基于组件树结构的事件流方式有时让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。

不过我们可以自行实现 dispatch 和 broadcast 方法,用于组件的跨层级通信。它们实现的关键在于如何正确找到所要通信的组件,也就是通过匹配组件的 name 选项向下或向上查找组件。

这两个方法都需要传递 3 个参数,第一个参数是要通信组件的 name 选项值,第二个是自定义事件名称,第三个是要给通信组件传递的值。在 dispatch 里,通过 while 循环不断向上查找父组件,直到查找到 componentName 与某个父级组件的 name 选项匹配时结束,此时改父组件就是要通信的组件。 broadcast 方法与 dispatch 类似,是通过 forEach 循环向下查找子组件。 最后封装一个 mixins 来便于复用。

// emitter.js 
function broadcast(componentName, eventName, params) {
  this.$children.forEach(child => {
    const name = child.$options.name;
    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      let parent = this.$parent || this.$root;
      let name = parent.$options.name;
      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.name;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

通过 mixins 混入组件,实现组件间的通信。





相比 Vue 1.0 版本内置的两个 API,自行实现的方法有以下不同:

需要额外传入组件的 name 作为第一个参数;

匹配到组件就会停止循环,不会冒泡;

传递的值只能是一个参数,如果需要传递多个参数,只能通过对象或数组的形式;

其他方法

在 vue 中组件的通信还有其他的手法,例如:

props$emit





父组件将自己的方法传递给子组件,子组件调用方法传数据给父组件

使用event bus事件总线

$attrs$listeners

Vue 2.4 新增的 API。$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。

Vuex 集中式状态管理

写在最后

不同的通信方法适用于不同的场景,既可以通过 Vue 内置的 API 来通信,也可以通过自定义事件的方式实现通信方法,当应用足够复杂情况下,就可以使用 Vuex 进行数据管理。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102670.html

相关文章

  • 聊聊Vue.js组件通信几种姿势

    摘要:子组件向父组件通信方法一使用事件父组件向子组件传递事件方法,子组件通过触发事件,回调给父组件。非父子组件兄弟组件之间的数据传递非父子组件通信,官方推荐使用一个实例作为中央事件总线。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。 文章的原地址:https://github.com/answ...

    Profeel 评论0 收藏0
  • 浅谈Vue 中的组件

    摘要:浅谈中的组件一初识组件组件是最强大的功能之一。组件可以扩展元素,封装可重用的代码。例子我是组件我要把中的数据传给我是组件中央事件总线我是用来接收从传过来的数据我是中的数据我是根组件的数据 浅谈 vue 中的组件 一 、初识组件 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。 1、定义组件 Vue自定义组件分为两种:全局...

    ls0609 评论0 收藏0
  • vue组件通信六种方式(完整版)

    摘要:本文总结了组件间通信的几种方式,如和,以通俗易懂的实例讲述这其中的差别及使用场景,希望对小伙伴有些许帮助。状态改变提交操作方法。前言 组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系: showImg(https://user-gold-cdn.xitu.io/2019/5/17/16ac35bf...

    DDreach 评论0 收藏0
  • vue组件通信六种方式(完整版)

    摘要:本文总结了组件间通信的几种方式,如和,以通俗易懂的实例讲述这其中的差别及使用场景,希望对小伙伴有些许帮助。状态改变提交操作方法。 前言 组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:showImg(https://segmentfault.com/img/remote/146000001...

    frontoldman 评论0 收藏0
  • React 中组件通信几种方式

    摘要:在使用的过程中,不可避免的需要组件间进行消息传递通信,组件间通信大体有下面几种情况父组件向子组件通信子组件向父组件通信非嵌套组件间通信跨级组件之间通信父组件向子组件通信父组件通过向子组件传递,子组件得到后进行相应的处理。 在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 非嵌套组件间通信 跨...

    Anshiii 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<