课程大纲

  • (1)组件绑定原生事件
  • (2)监听器属性$listeners
  • (3) r e f 与 ref与 refrefs注册引用信息属性和对象

组件绑定原生事件

  • 有时,我们想要在一个组件的根元素上直接监听一个原生事件,一般操作步骤如下
  • 1、首先定义一个 child 组件,什么事件都不绑定,代码如下:

在这里插入图片描述

  • 2、接下来,给 child 组件增加一个 @click 事件,如下所示
    在这里插入图片描述

  • 3、这个 handleClick 方法是谁的呢?当然是父作用域下的方法,所以接下来在根组件中增加一个方法,代码如下
    在这里插入图片描述

  • 分析验证:

  • 当点击按钮的时候发现,没有弹框提示,也就是说 handleClick 方法根本没有执行,究其原因,在于此时组件绑定事件等价于自定义事件。

  • 方案:

  • 通过 $emit 事件派发传递给父组件,代码如下所示:
    在这里插入图片描述

  • 分析验证:
    this.$emit方法也可以传递参数,修改代码,如下所示
    在这里插入图片描述

  • 组件绑定原生事件:
    如上代码,在组件上绑定原生事件还需要自定义事件,过于麻烦。这个时候 .native 原生修饰符就派上用场了,代码如下
    在这里插入图片描述

  • .native 原生修饰符的官方解释是: 监听组件根元素的原生事件!

  • 接下来再看个案例,给组件根元素添加.native绑定原生事件(onblur失焦事件),即失焦时触发
    在这里插入图片描述

  • 优化:
    为了提高用户体验,我们将根元素改为<label>,调整如下
    在这里插入图片描述

  • 验证后发现,此时原生事件不能被正常触发,即使用了.native也无效。

  • 所以根元素为<label>时,原生事件不能再被绑定到input事件上。父级的 .native 监听器将静默失败。它不会产生任何报错,但是处理函数不会如你预期地被调用。

组件绑定原生事件和$listeners

  • 监听属性$listeners :
  • 为了解决这个问题,Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了在这个组件上的所有监听器
  • 注意:使用.native修饰符的事件,不会体现在$listeners属性上。
  • 场景:
    当组件的根元素不具备一些DOM事件,但是根元素内部元素具备相对应的DOM事件,那么可以使用$listeners获取父组件传递进来的所有事件函数,再通过v-on="xxxx"绑定到相对应的内部元素上即可。
  • 分析:
    • 因为child组件的外层根元素是一个label元素,所以默认情况下使用v-on:blur是无效的,所以需要配合$listeners使用,该属性可以把事件的监听指向组件中某个特定的元素
    • 注意:再次强调,如果父级的事件添加了.native修饰符,在$listeners中不会体现出来的
  • 监听属性$listeners案例 :
    在这里插入图片描述
  • 监听属性$listeners:
    目前为止, <child> 组件便是一个完全透明的包裹器了,也就是说它可以完全像一个普通的 <input> 元素一样使用了:所有跟它相同的特性和监听器的都可以工作。
  • 小结:
    1、组件根元素添加.native表示绑定原生事件
    2、在开发里常通过props把构造器中data的值传递给组件,我们只要进行绑定就可以了,就是我们之前所介绍的v-bind:xxx
    3、构造器即平时所说的Vue实例

基础扫盲

  • 这里简单介绍几个vue小技巧
  • 1、$ listeners,它是一个对象,里面包含了作用在这个组件上的所有监听器,你就可以配合 v-on="$listeners"
    将所有的事件监听器指向这个组件的某个特定的子元素。
  • 2、引用下vue的官方api中对 a t t r s 的 说 明 : attrs的说明: attrsattrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定
    (class 和 style 除外)
  • 3、$listeners(自下而上传递数据), $attrs(自上而下多组件传递数据)

$listeners

  • $listeners常用于组件由下向上回传事件,通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
  • 跨级通信方案
  • 使用$attrs$listeners实现祖孙组件之间的数据传递,也就是多重嵌套组件之间的数据传递
$attrs----向下传递
$listeners----向上传递

跨级组件传值通信

  • 假设第三层组件想和第一层组件进行通信
    • 1、(第一层组件向第三层组件传值)—禁止第一层直接传值到第三层,需要逐层传递,即1→2→3,此时便可以实现跨级组件向下通信
    • 2、(第三层组件向第一层组件传值)—通过触发自定义事件将数据传递至第二层,然后第二层通过事件触发传递至第一层,如此逐层传递,便可以实现跨级组件向上通信
      在这里插入图片描述
  • 首先测试下跨级通信中的向下通信
    在这里插入图片描述
    上图知识点:非props特性+inheritAttrs+$attrs
    文本插值:$attrs文本显示语法$attrs['属性名']
    跨级向上通信:
  • 接下来测试下跨级向上通信
    在这里插入图片描述
    上图知识点:
   v-on=”$listener”绑定+this.$listeners.方法名(参数)

分析:
二级组件中能直接触发最高级组件事件的原因在于调用组件时使用 v-on 绑定了$listeners 属性

  • 接下来添加数据操作,因为单向数据流规定:后代组件不可以直接修改父组件传值,所以需要在后代组件里设置传值缓存,然后再事件回传.
    在这里插入图片描述

数据传递

  • 简单总结下数据传递方向
  • 之前使用 $attrs 实现数据的向下传递, 但是又怎么实现下层数据或事件的向上交互呢? 这里就要使用到 $listeners
  • $attrs是向下传递数据, $listeners 是向上传递方法,接受对象里的方法,来触发从父级接受来的函数。

$ref与$refs

  • 官方文档描述$refs下图:

在这里插入图片描述

  • 官方文档描述$ref下图:
    在这里插入图片描述

$ref与$refs

  • $ref用法大概分为两种,普通DOM元素用法和组件用法

  • (1)普通DOM元素用法

  • 有时Vue项目需要操作DOM节点,所以需要获取DOM。一般来讲,获取DOM元素,需document.querySelector()获取这个dom节点,然后才能进一步操作。
    在这里插入图片描述

  • (1)普通DOM元素用法
    旧版做法,document.querySelector()获取节点然后操作,下图:
    在这里插入图片描述
    新版做法:用ref绑定之后,我们就不需要在获取dom节点了,直接在上面的input上绑定 r e f , 然 后 通 过 ref,然后通过 refrefs.$ref即可调用,这样就可以减少获取dom节点的消耗。下图:
    在这里插入图片描述
    -( 2)组件component用法

  • 案例:利用组件,实现计数器count效果

  • 1、首先封装个简单的组件,每次点击+1,调用两次
    在这里插入图片描述

  • 2、接下来,想在HTML模板里获取两个组件次数的和。此时需要在父组件获取子组件的状态变化,即自定义事件,利用发布订阅模式。下图:
    在这里插入图片描述

  • (2)组件component用法
    最后,获取两个组件实例单独的数据,相加即可
    在这里插入图片描述

  • 官方文档描述小结:

    • $ref:注册引用信息属性,用来给元素或子组件注册引用信息。
    • $refs:一个对象,持有已经注册过ref的所有子组件。
  • 通俗理解:

  • $ref:注册引用信息属性

    • $refs:注册引用信息对象
  • $ref含义:

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

  • $ref 三种用法:

    • 1、ref 加在普通的元素上,用this.ref.name 获取到的是dom元素
    • 2、ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。
    • 3、利用 v-for 和 ref 获取一组数组或者dom 节点

小结:

  • 1、$ref:被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs对象上。如果在普通的DOM元素上使用,那么指向的就是普通的DOM元素
  • 2、$refs:一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例
    注意:refs只会在组件渲染完成之后生效,并且它们不是响应式的。这只意味着一个直接的子组件封装的“逃生舱”——你应该避免在模板或计算属性中访问 $refs 。

完毕…

Logo

前往低代码交流专区

更多推荐