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 arguments,jcallee caller用法总结
Nov 30 Javascript
js判断滚动条是否已到页面最底部或顶部实例
Nov 20 Javascript
调试JavaScript中正则表达式中遇到的问题
Jan 27 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
Apr 15 Javascript
清除js缓存的多种方法总结
Dec 09 Javascript
基于JQuery的购物车添加删除以及结算功能示例
Mar 08 Javascript
jQuery实现可拖动进度条实例代码
Jun 21 jQuery
浅谈express 中间件机制及实现原理
Aug 31 Javascript
laypage+SpringMVC实现后端分页
Jul 27 Javascript
Vue项目打包部署到iis服务器的配置方法
Oct 14 Javascript
使用layui前端框架弹出form表单以及提交的示例
Oct 25 Javascript
微信小程序搜索框样式并实现跳转到搜索页面(小程序搜索功能)
Mar 10 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
Php-Redis安装测试笔记
2015/03/05 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
JS判断不能为空实例代码
2013/11/26 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
2014/09/23 Javascript
微信分享的标题、缩略图、连接及描述设置方法
2014/10/14 Javascript
限制上传文件大小和格式的jQuery插件实例
2015/01/24 Javascript
用JavaScript实现对话框的教程
2015/06/04 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
2016/05/10 Javascript
学习 NodeJS 第八天:Socket 通讯实例
2016/12/21 NodeJs
jQuery实现滚动条滚动到子元素位置(方便定位)
2017/01/08 Javascript
为JQuery EasyUI 表单组件增加焦点切换功能的方法
2017/04/13 jQuery
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
解决vue接口数据赋值给data没有反应的问题
2018/08/27 Javascript
这15个Vue指令,让你的项目开发爽到爆
2019/10/11 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
vue实现放大镜效果
2020/09/17 Javascript
python基于ID3思想的决策树
2018/01/03 Python
详解pandas数据合并与重塑(pd.concat篇)
2019/07/09 Python
django框架用户权限中的session缓存到redis中的方法
2019/08/06 Python
Python request操作步骤及代码实例
2020/04/13 Python
pycharm最新激活码有效期至2100年(亲测可用)
2021/02/05 Python
学生会主席就职演讲稿
2014/01/14 职场文书
全民健身日活动方案
2014/01/29 职场文书
小学生竞选班长演讲稿
2014/04/24 职场文书
课程设计的心得体会
2014/09/03 职场文书
大学生自我评价200字(4篇)
2014/09/17 职场文书
公司捐书倡议书
2015/04/27 职场文书
复兴之路展览观后感
2015/06/02 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
小学作文之描写天气
2019/08/15 职场文书
Linux安装Nginx步骤详解
2021/03/31 Servers
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL
在SQL Server中使用 Try Catch 处理异常的示例详解
2022/07/15 SQL Server