本篇文章记录仿写一个el-tooltip
组件细节,从而有助于大家更好理解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续空闲了会不断更新并仿写其他组件。源码在github上,大家可以拉下来,npm start运行跑起来,结合注释有助于更好的理解。github仓库地址如下:
https://github.com/shuirongsh...
前言
什么是编程
关于什么是编程这个问题,的确有很多答案。在很久以前,在笔者刚入行的时候,被告知了这样一句话:
编程就是:规则的学习,规则的使用,规则的理解、规则的自定义
有一定的道理...
背景介绍
我们在做组件的封装时,常常会遇到一些“弹框组件”,以饿了么UI为例,比如:el-tooltip组件
、el-popover组件
、el-popconfirm组件
、el-dropdown组件
等,这类组件在操作的时候,常常会有一个弹框出现,对于这些弹框的触发条件(或悬浮、或点击)以及位置的控制(上方、下方、左侧、右侧)等,vue团队专门封装了一个vue-popper组件
,通过props
传参以及一些事件方法的方式,去控制以达到我们想要的效果
那么,vue-popper组件
是如何实现的呢?底层原理是啥?是把popper.js
这个很优秀的库做了一层封装
那么,popper.js
是如何实现的呢?底层原理是啥?是通过js
控制弹出框dom
的位置
由于popper.js
国内资料不多,所以大家可以直接使用vue-popper组件
组件去做一些操作即可,毕竟其底层原理,也是prpper.js
el-tooltip组件
是使用了vue-popper组件
的规则vue-popper组件
是使用了popper.js库
的规则popper.js库
是使用了js和dom
的规则- 无限规则套娃...
附上传送门
prpper.js
官网:https://popper.js.org/、中文...感兴趣的道友,可以空闲时间研究研究(像
elementUI
和iview
和Bootstrap
和Material UI
等都用到了proper.js
)也是做的二次封装另:
prpper.js
团队专门给react
写了一套React Popper
,vue
暂时没有,所以咱们就学习vue-popper
呗
本篇文章着眼于,中层底层原理vue-popper组件
,让我们开始学习吧
tooltip组件思考
什么是tooltip组件
- tooltip组件是用来做简单的文字附带说明(提示)的气泡框组件
- 一般交互是鼠标移入显示,鼠标移出消失
- tooltip组件一般不会做复杂的交互操作,以及承载过多的文本内容
- 可以理解为是dom元素title属性功能的具体补充
tooltip组件需求
- 暗黑模式tooltip,黑底白字
- 高亮模式tooltip,白底黑字
- tooltip组件的位置,在指向引用reference元素的那个方向,一般是上下左右,拓展共有12个方向
- tooltip的小三角形(一般是显示的)
- 可控制关闭开启,即符合条件hover展示,反之hover关闭
- 一般情况下tooltip都是单行内容,若内容过多,支持文字换行乃至自定义tooltip一些样式(支持插槽)
- 至于其他的需求如:tooltip显示展开的过渡动画、小箭头是否可以隐藏、以及偏移量offset、延迟出现消失等,一般情况下不会怎么更改,所以本文着眼于重点常见需求,来进行说明
在使用库或者一些基础组件之前,我们先尝试一下,手写一下
一个简单的tooltip的demo
主要是使用属性选择器去控制,四个方向的tooltip和三角形小箭头。
标签的whichPlacement属性值为"top"时
,就让其在上方,为left时
,就让其在左侧,其他方位同理
demo效果图
demo代码
复制粘贴即可使用
Document
悬浮上方
悬浮下方
悬浮左侧
悬浮右侧
关于css属性选择器和attr()函数
上述代码中用到了属性选择器和attr()函数,这里简单的提一下
属性选择器
问:什么是属性选择器?
答1:通过选取带有指定标签属性的dom元素,进行样式的设置
答2:通过标签的属性名key和属性值value来匹配元素,从而进行样式的设置
问:举个例子呗
答:
[attr]
匹配所有具有attr
属性的元素,不用管其值是什么,如:input[type]{ ... }
,意为:只要input
标签中,包含type
属性(忽略type
属性值),都选中,并设置...
样式[attr='val']
匹配所有attr
属性值等于val
,完全精准匹配。如:input[type='text']{ ... }
,意为:只要input
标签中,有type
属性,且属性值为text
,才去选中,并匹配...
样式[attr^='val']
匹配所有attr
属性值以val
开头的(上述demo案例中就用到了,只不过其属性是我们自定义的)。模糊匹配[attr$='val']
,同上类似,^=
是以什么什么开头匹配,$=
是以什么什么结尾匹配。模糊匹配[attr*='val']
,同上类似,*=
是只要包含即可,也是模糊匹配
详见官方属性选择器介绍:https://www.w3school.com.cn/c...
attr()函数
attr
是attribute
单词属性
的缩写,顾名思义,所以这个东西和属性有关
css
的函数attr()
可获取被选中元素的属性值
,并且在样式文件中使用。可用在伪元素里,在伪类元素里使用,它得到的是伪元素的原始元素的值。attr()
函数可以和任何css
属性一起使用,但是除了content
外,其余都还是试验性的,所以建议:除了搭配伪元素的content
别的都不要用
如上述案例:
悬浮上方
.item::after {
/* 使用选中标签的tooltipContent属性值作为content的内容 */
content: attr(tooltipContent);
}
官方attr函数介绍:https://developer.mozilla.org...
为什么要说属性选择器呢?因为封装的代码中能够用到啊
使用vue-popper
做组件的封装
安装
// CDN
// NPM
npm install vue-popperjs --save
// Yarn
yarn add vue-popperjs
// Bower
bower install vue-popperjs --save
官方案例demo
Popper Content
官方demo效果图
笔者的二次封装效果图
使用之代码
下方代码较多,建议打开编辑器,复制粘贴代码,跑起来,阅读之
暗色模式
上方左侧上方左侧
上方中间
上方右侧上方右侧
左侧上方
左侧中间
左侧下方
右侧上方
右侧中间
右侧下方
下方左侧下方左侧
下方中间
下方右侧下方右侧
亮色模式
上方左侧上方左侧
上方中间
上方右侧上方右侧
左侧上方
左侧中间
左侧下方
右侧上方
右侧中间
右侧下方
下方左侧下方左侧
下方中间
下方右侧下方右侧
可禁用
悬浮出现
当tooltip内容多的时候,使用content插槽
内容过多时,使用插槽更便于控制样式,比如换行
悬浮出现
mytooltip
封装代码
{{ content }}
总结
因为mytooltip
组件,需要使用到的vue-popper
属性和方法并不多,所以大家可以仿照笔者的方式,去看一下vue-popper
组件的代码,然后结合自己公司的业务需求,去封装一些适合自己公司的弹框组件
vue-popper
:https://github.com/RobinCK/vu...当然,时间较为充裕的可以看一下
popper.js
这个库
关于vue-popper
组件的其他二次封装的应用,如封装el-popover组件
、el-popconfirm组件
、el-dropdown组件
等,笔者会陆续更新的。不同的组件用到vue-popper
不同的属性和方法
墙裂建议大家,看完以后,自己手写一下。只是看一遍,学习效果不太好