Vue组件通信$attrs、$listeners实现原理解析


Posted in Javascript onSeptember 03, 2020

前言

vue通信手段有很多种,props/emit、vuex、event bus、provide/inject 等。还有一种通信方式,那就是$attrs和$listeners,之前早就听说这两个api,趁着有空来补补。这种方式挺优雅,使用起来也不赖。下面例子都会通过父、子、孙子,三者的关系来说明使用方式。

Vue组件通信$attrs、$listeners实现原理解析

$attrs

官方解释:

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

我的理解:

接收除了props声明外的所有绑定属性(class、style除外)

图解:

Vue组件通信$attrs、$listeners实现原理解析

由于child.vue 在 props 中声明了 name 属性,$attrs 中只有age、gender两个属性,输出结果为:

{age: "20",gender: "man"}

Vue组件通信$attrs、$listeners实现原理解析

另外可以在 grandson.vue 上通过 v-bind="$attrs", 可以将属性继续向下传递,让 grandson.vue 也能访问到父组件的属性,这在传递多个属性时会显得很便捷,而不用一条条的进行绑定。

如果想要添加其他属性,可继续绑定属性。但要注意的是,继续绑定的属性和 $attrs 中的属性有重复时,继续绑定的属性优先级会更高。

$listeners

官方解释:

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

我的理解:

接收除了带有.native事件修饰符的所有事件监听器

图解:

Vue组件通信$attrs、$listeners实现原理解析

parent.vue中对 child.vue 绑定了两个事件,带有.native的 click 事件和一个自定义事件,所以在 child.vue 中,输出$listeners的结果为:

{ customEvent: fn }

Vue组件通信$attrs、$listeners实现原理解析

同 attrs 属性一样,可以通过 v-on="$listeners",将事件监听器继续向下传递,让 grandson.vue 访问到事件,且可以使用 $emit 触发 parent.vue 的函数。

如果想要添加其他事件监听器,可继续绑定事件。但要注意的是,继续绑定的事件和 $listeners 中的事件有重复时,不会被覆盖。当 grandson.vue 触发 customEvent 时,child.vue 和 parent.vue 的事件都会被触发,触发顺序类似于冒泡,先到 child.vue 再到 parent.vue。

使用场景:

组件传值时使用: 爷爷在父亲组件传递值,父亲组件会通过$attrs获取到不在父亲props里面的所有属性,父亲组件通过在孙子组件上绑定$attrs 和 $listeners 使孙组件获取爷爷传递的值并且可以调用在爷爷那里定义的方法;

对一些UI库进行二次封装时使用:比如element-ui,里面的组件不能满足自己的使用场景的时候,会二次封装,但是又想保留他自己的属性和方法,那么这个时候时候$attrs和$listners是个完美的解决方案。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
优秀js开源框架-jQuery使用手册(1)
Mar 10 Javascript
JavaScript 自动分号插入(JavaScript synat:auto semicolon insertion)
Nov 04 Javascript
javascript权威指南 学习笔记之javascript数据类型
Sep 24 Javascript
jquery 之 $().hover(func1, funct2)使用方法
Jun 14 Javascript
ie支持function.bind()方法实现代码
Dec 27 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
JS中如何设置readOnly的值
Dec 25 Javascript
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
Aug 20 Javascript
js中键盘事件实例简析
Jan 10 Javascript
微信小程序自定义导航栏实例代码
Apr 05 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
Jul 16 Javascript
js实现简单五子棋游戏
May 28 Javascript
Vue父组件监听子组件生命周期
Sep 03 #Javascript
JavaScript 几种循环方式以及模块化的总结
Sep 03 #Javascript
Vuejs通过拖动改变元素宽度实现自适应
Sep 02 #Javascript
Vue Object.defineProperty及ProxyVue实现双向数据绑定
Sep 02 #Javascript
Vue 组件的挂载与父子组件的传值实例
Sep 02 #Javascript
vue中的.$mount('#app')手动挂载操作
Sep 02 #Javascript
vue中提示$index is not defined错误的解决方式
Sep 02 #Javascript
You might like
第六节--访问属性和方法
2006/11/16 PHP
Yii2实现让关联字段支持搜索功能的方法
2016/08/10 PHP
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
JS 实现双色表格实现代码
2009/11/24 Javascript
javascript 函数速查表
2010/02/07 Javascript
如何确保JavaScript的执行顺序 之实战篇
2011/03/03 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
2013/09/18 Javascript
教你如何终止JQUERY的$.AJAX请求
2016/02/23 Javascript
json与jsonp知识小结(推荐)
2016/08/16 Javascript
webpack多页面开发实践
2017/12/18 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
vue组件之间数据传递的方法实例分析
2019/02/12 Javascript
vue element自定义表单验证请求后端接口验证
2019/12/11 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
js实现简单选项卡制作
2020/08/05 Javascript
解决ant Design中Select设置initialValue时的大坑
2020/10/29 Javascript
react中hook介绍以及使用教程
2020/12/11 Javascript
[01:14:35]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第一局
2016/02/26 DOTA
[05:09]第二届DOTA2亚洲邀请赛决赛日比赛集锦:iG 3:0 OG夺冠
2017/04/05 DOTA
Python基于正则表达式实现检查文件内容的方法【文件检索】
2017/08/30 Python
python执行系统命令后获取返回值的几种方式集合
2018/05/12 Python
python绘制热力图heatmap
2020/03/23 Python
Python 实现文件读写、坐标寻址、查找替换功能
2019/09/11 Python
实例讲解使用CSS实现多边框和透明边框的方法
2015/09/08 HTML / CSS
HTML5中如何显示视频呢 HTML5视频播放demo
2013/06/08 HTML / CSS
粉红色的鲸鱼:Vineyard Vines
2018/02/17 全球购物
澳大利亚在线购买葡萄酒:The Wine Collective
2020/02/20 全球购物
编写一子程序,将一链表倒序,即使链表表尾变表头,表头变表尾
2016/02/10 面试题
银行求职信个人范文
2013/12/16 职场文书
公司员工检讨书
2014/02/08 职场文书
党员民主生活会整改措施
2014/09/26 职场文书
对外汉语专业大学生职业生涯规划书
2014/10/11 职场文书
Pytorch实现图像识别之数字识别(附详细注释)
2021/05/11 Python
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
Python函数对象与闭包函数
2022/04/13 Python
mysql 体系结构和存储引擎介绍
2022/05/06 MySQL