vue组件间通信的八大方法

再读vue官方文档系列文章目录

  1. vue组件间通信的八大方法


前言

刚开始学vue的时候只是读了一遍官方文档,这样带来的后果是不够深入。本系列记录再次深入读vue官方文档及一些vue源码。


提示:以下是本篇文章正文内容,简单使用,下面案例可供参考

一、通信种类?

其实就是3中

  • 父子通信
  • 兄弟通信
  • 跨代通信
    在这里插入图片描述

二、八大通信方式

1. props和 $emit

这个使用率可能有80%了吧

  • props 父->子

父组件 v-bind 动态传参 或者直接静态传参给子组件的props
<parent v-bind:propsname='响应式数据'></parent>
或者
<parent propsname='静态数据'></parent>
子组件用vm.props接收即可

源码这里不够地方了。

  • $emit 子->父
 子:$emit(event,args...)
 父: <parent v-on:event='callback'></parent>
  • $on:监听事件
  • $off:移除监听事件
  • $emit:触发事件

粗略讲一下原理:

  • 每个vue实例都有vm._events{eventName:[cb1,cb2,cb3,..]...}对象,用来保存监听的事件 ,键值名为事件名,值为回调事件数组(允许多个回调)
  • vm.$on(event)负责把事件与回调加入events中
  • $emit(event,args):触发事件,核心源码
  • vm._events.[event].forEach(cb=>{cb.apply(vm, args)})
    本质是:子组件在父组件环境里监听一个事件,子组件触发事件时,子组件在父组件环境执行父组件的函数作为回调。

一个有趣的是子组件里面也是可以监听自己,并触发自己的回调。

 methods: {
    dc() {
        this.$on('event',this.cbd)
        
        this.$emit("event");
    },
    cbd(){
        console.log('i am D');
    }
  },

有空把props emit 源码写一下就知道为啥了。

2. $parent和 $children

通过vm. p a r e n t , 能 拿 到 父 组 件 实 例 , v m . parent,能拿到父组件实例, vm. parent,,vm.children 子组件实例数组,但是这个官方不推荐使用
测试了一下也能修改父组件data

3. provide和reject

官方描述

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

A组件

export default {
  name: "",
  props: [""],
  provide:{
      provideData:'我是A provide过来的'
  },...}

BCDE组件

export default {
  name: "",
  props: [""],
  data() {
    return {
    };
  },
  inject:['provideData'],
  }
<template>
  <div class="C">
    我是<button @click="clickC">C</button>
    {{provideData}}
    <E> </E>
  </div>
</template>

效果
在这里插入图片描述

4. ref/refs

ref:官方描述

被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM
元素;如果用在子组件上,引用就指向组件实例

refs:(注意不是响应式数据)

一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例。
  • 本质获取本页的dom 或者本组件的子组件引用
    A:
<template>
  <div class="A">
    我是A
    <div>
      <B message='我是A传过来的消息' v-on:event="cb1"></B>
      <C ref='C'></C>
      <p ref='p'></p>
    </div>
  </div>
  
 mounted() {
    console.log(this.$refs);//{C: VueComponent, p: p}
  },

5. Vuex

这个都不用说了吧,跨组件通信,每个组件都可以获取到。

6. slot

只能单向传递数据

7. $attrs 和 $listeners

$attrs

包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

$listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。

官网描述有点抽象,举个列子。

  • A 想传两个prop a=1,和b = 2 ,
  • 其中a传给子组件C ,b传给跨代子组件E,这个时候就可以用$attr
  • 同时我想在E组件触发A的事件回调(和emit 一个道理)。
    A:
<template>
  <div class="A">
    我是A
    <div>
      <C ref='C' a="1" b='2' v-on:Eevent='callBack'></C>
    </div>
  </div>
</template>

 methods: {
      callBack(){
          console.log('我从E中触发');
      }
  },

C:

<template>
  <div class="C">
    我是<button @click="clickC">C</button>
    <E v-bind="$attrs" v-on="$listeners"></E>
  </div>
</template>
 mounted() {
      console.log(this.$attrs);//b=2
  },

这里说明一下:v-bind="$attrs" 把从A接受了两个a=1,b=2, 但是a 在C组件的prop里面,所以只把b=2继续传给E组件

E:

<template>
  <div class="E" @click="clickC">我是E</div>
</template>
methods: {
      clickC(){
          console.log(this.$attrs);//b=2
          this.$listeners.Eevent()
      }
  },

8. localStorage和sessionStorage

这个也差不多,把信息存在localStorage,每个组件都可以获取到.

其实还有个eventBus 没在vue2官方文档看到,以后用到再说。


总结

兄弟通信 vuex
跨级通信:vuex provide/inject $attrs/ $listerner
父子:上面都可以
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值