Vue之组件(绑定原生事件、$listeners、$ref)
课程大纲
- (1)组件绑定原生事件
- (2)监听器属性$listeners
- (3) r e f 与 ref与 ref与refs注册引用信息属性和对象
组件绑定原生事件
- 有时,我们想要在一个组件的根元素上直接监听一个原生事件,一般操作步骤如下
- 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的说明: attrs的说明:attrs包含了父作用域中不作为 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,然后通过 ref,然后通过refs.$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 。
还没有评论,来说两句吧...