组件库源码中这些写法你掌握了吗?(上)

简介: 前沿:这几年,前端的组件库的演变迅速,社区脱颖而出不少优秀的开源组件库,包括element-ui、Ant design、IView等等,这些开源组件库源码中其实有很多值得我们学习的地方,无论是设计思路,代码风格等等,可以通过参考源码中一些写法,引用到我们平时的项目中去。

微信截图_20220514081332.png


前沿:这几年,前端的组件库的演变迅速,社区脱颖而出不少优秀的开源组件库,包括element-ui、Ant design、IView等等,这些开源组件库源码中其实有很多值得我们学习的地方,无论是设计思路,代码风格等等,可以通过参考源码中一些写法,引用到我们平时的项目中去。


1.Directives (指令)


在vue中我们可以通过自定义指令,来对DOM元素进行底层操作,我们顺便复习下如何自定义一个指令,主要包含5个钩子函数,这里只列出几个比较常用的钩子函数,最后再介绍组件库常见的一些自定义指令


Vue.directive("directiveName", {
  bind: function(el, binding, vnode){
   # 当指令第一次绑定元素el时触发,常用来做初始化
  },
  update: function(el, binding, vnode) {
   # 绑定Vue编译生成的虚拟节点VNode 更新时调用
  },
  unbind: function(el, binding, vnode) {
   # 解绑操作,用来将指令和元素解绑时调用,类似vue生命周期中的beforeDestroy钩子函数
  }
});


1.1 v-clickoutside


v-clickoutside是Element-ui实现的一个自定义指令,目的是用来处理点击元素外面才会触发的事件,常用来处理下拉菜单等展开内容的关闭,在Element-ui的Select选择器、Dropdown下拉菜单、Popover 弹出框等组件中都用到了该指令


  • element的实现


element的 clickoutside 的具体实现,如下👇,更多源码详情看链接 element/src/utils/clickoutside.js  


微信截图_20220514081347.png


下面我们大概解读下这段代码的三个钩子函数内的逻辑


  • bind: 将绑定clickoutside指令的dom的el通过push到nodeList存起来,目的在于管理每次有 clickoutside 指令绑定到页面上,都会将绑定元素存储到 nodeList 中去。通过自增的临时变量 id来标识该 clickoutside 指令
  • update: 其实本质上就是用来更新初始化我们定义绑定在el的ctx中的值,方便组件更新时做变更
  • unbind:当需要将指令和元素el解绑时,通过遍历原先的“元素管理器“ - nodeList 的长度和结合上文提到的id找到 nodeList 中存储的当前解绑元素 el,将它从nodeList中删除


下图是一个bind的结果


微信截图_20220514081359.png


👦 啊斌同学:那clickoutside是怎么判断是否为点击外部?


答案:是bind中使用的createDocumentHandler()


  • createDocumentHandler() :就是用来区分当前点击的区域是否为指令绑定的dom,本质上是contains方法,好比某A元素包含B元素,则返回true,否则 false 。用来判断元素所处的位置,简单来说点击绑定v-clickoutside绑定的元素则不触发clickoutside 指令的逻辑,点击不包含区域则触发指令绑定的binding.value,我们看下源码向下


微信截图_20220514081414.png


👧 啊琪同学:这个组件的指令,我想自己项目中使用咋搞哦?


答案:跟平常引用的指令一样的方式,可以参考源码中引用 链接


微信截图_20220514081428.png


  • IView的实现


👧 啊呆弟弟:那其他组件库这种情况怎么实现的呢?


答案:像iview源码中clickoutside引入了v-click-outside-x作为依赖,感兴趣的童鞋可以看文档链接


微信截图_20220514081441.png


1.2 v-repeat-click


v-repeat-clickr顾名思义就是"重复点击、用于函数防抖",结合dom.js中的on和once方法。element将v-repeat-clickr应用于el-input-number组件,当你点击



微信截图_20220514081452.png


微信截图_20220514081505.png


当我们长按+或者-时,本质上只会触发一次触发mousedown的回调,但我们会发现输入框中的数字会不断递增?让我们先看看源码 源码链接


微信截图_20220514081523.png


啊森同学:那数字会变,那不是一直触发?


答案:repeat-click在mousedown的回调函数中加入了定时器,当鼠标松开,触发一次mouseup回调方法,然后根据时间间隔来执行


  • 如果时间间隔大于100毫秒,mousedown的回调方法里的setInterval回调函数就会执行handler函数(本质上是数字的decrease或increase)
  • 如果时间间隔小于100毫秒,定时器就会取消,通过once方法注册并执行一次mouseup回调


拓展:我们看看domjs中on及once的定义


  • once: 注册事件监听器并只允许执行一次,然后取消监听方法


微信截图_20220514081536.png


相关文章
|
前端开发 JavaScript 测试技术
React组件开发规范
React组件开发规范
2434 1
|
缓存 负载均衡 监控
【微服务】一文读懂网关概念+Nginx正反向代理+负载均衡+Spring Cloud Gateway(多栗子)
不知道什么是网关?正向代理?反向代理?负载均衡?负载均衡策略?Nginx和Gateway的区别?假如这些你都不知道,没关系,本文举了大量通俗易懂的例子来阐述了这些概念,保证小白也能看懂,并且最后还提到了gateway的一些配置。
9816 2
【微服务】一文读懂网关概念+Nginx正反向代理+负载均衡+Spring Cloud Gateway(多栗子)
|
11月前
|
SQL NoSQL 关系型数据库
RDS PostgreSQL版发布 rds_duckdb 插件!
RDS PostgreSQL版内置DuckDB,结合列存储与向量化执行的优势,在RDS PG内实现复杂SQL查询加速和ETL功能,复杂查询效率提升30X,想了解更多rds_duckdb信息和讨论交流,欢迎加入RDS PG插件用户专项服务群(103525002795)
|
Java Linux Windows
如何查看已安装的 Java 版本
要查看已安装的 Java 版本,打开命令提示符或终端,输入 `java -version`,回车后即可显示当前系统中 Java 的版本信息。
4402 1
|
关系型数据库 MySQL 数据库
实现RDS MySQL实例数据迁移的详细步骤
实现RDS MySQL实例数据迁移的详细步骤 随着科技的飞速发展,数据库的应用越来越广泛,而数据迁移作为数据库管理的重要环节,其重要性不言而喻。本文将详细介绍如何使用数据传输服务(Data Transmission Service,简称DTS),实现将三节点企业系列的RDS MySQL实例的数据迁移到集群系列的RDS MySQL。
528 4
|
关系型数据库 MySQL 数据库
(简单成功版本)Mysql配置my.ini文件
(简单成功版本)Mysql配置my.ini文件
2492 0
(简单成功版本)Mysql配置my.ini文件
|
JavaScript
Proxy error: Could not proxy request错误解决
Proxy error: Could not proxy request错误解决
1105 0
|
SQL Java 关系型数据库
jdbc(insert,update,,create,以及各个类详解)
jdbc(insert,update,,create,以及各个类详解)
ModuleNotFoundError: No module named ‘exceptions‘
ModuleNotFoundError: No module named ‘exceptions‘
201 0