vue组件封装: vue-popper+FloatManager
文章目录
- 前言
- 效果展示
- 正文
- FloatManager
- vue-Popper
- attributes
- slots
- events
- 对vue-popper进一步封装
- html
- js
- css
- 过渡
- 写在最后
前言
考虑这样一类问题
在鼠标覆盖在link元素上面时,在link附近弹出一个toolTip。
在button点击后,弹出一个气泡确认框让用户确认是否继续执行。
在input输入时,弹出一个输入提示或者下拉框
- toolTip
- 气泡确认框
- 下拉框
对于这类元素我们给出以下定义:
从文档流中“弹出”并漂浮在目标元素附近的任何 UI 元素。 最常见的示例是工具提示,但它也包括弹出窗口、下拉菜单等。 所有这些都可以概括地描述为“popper”元素。
现在,如果要实现这些元素,我们可能要考虑以下因素:
覆盖问题: 元素的z-index不同往往会使得最终元素谁在最上层
**裁剪和溢出问题:**纯CSS弹出程序不会被阻止溢出剪辑边界,例如视口。如果靠近边缘,由于没有动态定位逻辑,它会被部分切断或溢出。使用 Popper 时,您的 popper 将始终位于正确的位置,无需手动调整。
**无翻转:**如有必要,CSS 弹出程序不会翻转到不同的位置以更好地适应视图。虽然您可以手动调整主轴溢出,但仅通过 CSS 无法实现此功能。 Popper 会自动翻转工具提示,使其尽可能适合用户。
**无虚拟定位:**CSS弹出程序不能跟随鼠标光标或用作上下文菜单。 Popper 允许您相对于您想要的任何坐标定位您的工具提示。
**较慢的开发周期:**当使用纯 CSS 来定位 popper 元素时,缺乏动态定位意味着必须仔细放置它们以考虑所有屏幕尺寸的溢出。在可重用组件库中,这意味着开发人员不能只是在页面的任何位置添加组件,因为每次都需要考虑和调整这些问题。使用 Popper,您可以将元素放置在任何地方并且它们将被正确定位,而无需考虑不同的屏幕尺寸、布局等。这大大加快了开发时间,因为这项工作会自动卸载到 Popper。
**缺乏可扩展性:**CSS 弹出层无法轻松扩展来适应您可能需要调整的任意用例。 Popper 在构建时考虑了可扩展性。
为了解决上述问题,我们使用vue-popper
vue-popper是Popper.JS的一层封装,更加适用于vue组件开发
而对于元素之间的覆盖问题,可以借鉴elementUI的管理思路:所有的popper元素的z-index随着出现顺序以此递增,也就是让新出现的弹出层,永远比之前所有弹出层的层级要高
在这里,我们将其命名为FloatManager,他将为我们管理所有的popper元素以及之后的msg元素
效果展示
1684249807016
正文
FloatManager
他的实现非常简单,直接看代码吧:
/*** 统一管理popper元素、msg元素 的层级属性* 使得新出现的定位元素层级永远比先前出现的要高*/class FloatManager {constructor() {this.zIndex = 2000;}nextZindex(){const res = this.zIndex;this.zIndex += 1;return res;}
}export default new FloatManager();
是的,就这么一个变量+一个函数就行,因为js模块化的特性,在不同地方引入的FloatManager实例都会是同一个实例,保证了nextZindex函数返回的zIndex永远递增。
vue-Popper
在对vue-popper进一步封装之前,介绍一些vue-popper的一些使用:
attributes
属性名 | 描述 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
disabled | 禁止popper元素出现 | boolean | — | false |
visable-arrow | 展示小箭头 | boolean | — | true |
force-show | 是否强制展示popper元素 | boolean | — | false |
trigger | 触发popper展示的事件 | string | hover / clickToOpen / … | hover |
root-class | popper根元素类名 | string | — | — |
append-to-body | 是否添加到body元素中 | boolean | — | false |
transition | 过渡动画的名字 | string | — | — |
enter-active-class | 进入动画的类名 | string | — | — |
leave-active-class | 离开动画的类名 | string | — | — |
delay-on-mouse-over | 触发popper元素show的延时 | number | — | 10 |
delay-on-mouse-out | 触发popper元素hide的延时 | number | — | 10 |
options | 原生Popper.JS的配置项 | object | — | — |
对于options配置项,展示只配置placement选项和offset选项
- placement: 控制popper元素定位到触发元素的上下左右
- offset:控制popper元素的触发元素的偏移量
- gpuAcceleration:控制是否使用GPU加速动画此选项至关重要,默认值是true,此时元素能够采用的过渡只有opacity一个,即使是设置了false,传入给vue-popper的动画会成功,但是popper元素的定位会出大问题,关于实现动画采用其他方式
slots
槽名 | 描述 |
---|---|
reference | 触发show()的元素 |
popper | popper元素 |
events
事件名 | 描述 | 回调参数 |
---|---|---|
show | popper元素展示之后的回调 | — |
hide | popper元素消失之后的回调 | — |
对vue-popper进一步封装
对options中的三个常用的属性提取出来作为props
增加max-width属性:用来控制popper元素的最大宽度, 默认值为2000px
增加min-width属性:用来控制popper元素的最小宽度, 默认值为0px
增加dark属性:用来控制popper元素的颜色主体是否是黑色
对vue-popper的控制动画的属性:
transition
、enter-active-class
、leave-active-class
采用固定值传入的过渡动画除了opacity之外全部会失效,采用别的方法实现动画过渡效果
html
<template><Popper:trigger="trigger":options="{placement: placement,modifiers:{offset: {offset:`0,${offset}`,},computeStyle: {gpuAcceleration: gpuAcceleration}},}"@hide="__hide()":force-show="forceShow":visible-arrow="showArrow":disabled="disabled":delay-on-mouse-out="delayOnMouseOut":delay-on-mouse-over="delayOnMouseIn":append-to-body="appendToBody"root-class="sss-popper-root"transition="sss-tra-temp"enter-active-class="sss-transition-temp-enter-active"leave-active-class="sss-transition-temp-leave-active"><!-- 固定--><slot slot="reference" name="reference"></slot><!-- 弹窗--><transition :name="`sss-transition-${transition}`"><div class="sss-popper" :class="popperClass" ref="popper" v-show="displayFlag"><slot name="popper"></slot></div></transition></Popper></template>
Q: gpuAcceleration
影响了什么?
A:这个属性实际上会影响popper元素的定位方式,当值为false时,popper元素将会采用
left top
来决定元素的定位、当值为true时,popper元素将会采用transform translate3d
进行定位。因此值为true的时候,设置任何transform作为过渡都会失效,如果强制设置又会使得定位出问题。
同样的值为false时,此时试着transform作为过渡属性也会值得定位出问题。
Q: 既然gpuAcceleration
会影响动画的执行,传入的transition
、enter-active-class
、leave-active-class
只有opacity起作用,为什么还要保留他们呢?
A:对于只需要opacity过渡的组件,比如tool-tip,采用GPU加速是一个很好的选择 。
后面三个配置项其实就是vue中transition组件需要的。保留的原因时为了做一个延时,因为popper提供的用得上的事件只有show和hide,前者是popper元素展示之后调用,后者是popper元素消失之后调用,没有beforeshow,beforehide事件,使得我们没有时间点来展示过渡动画。
/*用来给popper延时的*/
.sss-transition-temp-leave-active, .sss-transition-temp-enter-active {background-position: bottom;transition: background-position 3s linear;
}
.sss-transition-temp-enter, .sss-transition-temp-leave-to {background-position: bottom;
}
这里使用了不常用的background-position作为过渡,实际上就是为了这3s的延时。
<!-- 弹窗 --><transition :name="`sss-transition-${transition}`"><div class="sss-popper" :class="popperClass" ref="popper" v-show="displayFlag"><slot name="popper"></slot></div></transition>
相信看代码很容易看出,真正的过渡动画是在这里做的,为什么这样?问Popper.js的作者去,为什么要在整个元素外加一个span
vue组件封装: vue-popper+FloatManager相关推荐
- Vue 组件封装之 ScrollView 上拉加载更多
Vue 组件封装之 ScrollView 上拉加载更多 一.ScrollView 上拉加载更多 二.使用案例 三.API 使用指南 四.源代码 一.ScrollView 上拉加载更多 组件说明: 实现 ...
- Vue 组件封装之 Questionnaire 问卷调查
Vue 组件封装之 Questionnaire 问卷调查 前言 一.Questionnaire 组件 二.使用案例 三.API 使用指南 四.源代码 前言 问卷调查表也是目前前端比较常见的开发项目,目 ...
- Vue 组件封装之 Content 列表(处理多行输入框 textarea)
Vue 组件封装之 Content 列表 一.Content 列表 二.使用案例 三.API 使用指南 四.源代码 一.Content 列表 组件说明: 实现 Content 列表布局排版. 效果展示 ...
- Vue 组件封装之 List 列表
Vue 组件封装之 List 列表 一.List 列表 二.使用案例 三.API 使用指南 四.源代码 一.List 列表 组件说明: 实现 List 列表布局排版. 效果展示: 实现的功能: 在一个 ...
- Vue 组件封装之 Search 搜索
Vue 组件封装之 Search 搜索 一.Search 组件 二.使用案例 三.API 使用指南 四.源代码 一.Search 组件 组件说明: 实现搜索功能. 效果展示: input 输入框背景铺 ...
- Vue组件封装,(面试回答)
在我用vue开发项目的时候,一般我都会用到组件封装,采用组件化的思想进行项目开发,我在搭建一个项目的时候,就会创建一个views目录和一个commen目录和一个feature目录,views目录中放页 ...
- Vue 组件封装之 Tab 切换
Vue 组件封装之 tab 切换 一.Tab 切换组件 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tab 切换组件 组件说明: 实现 tab 切换. 效果展示: 实现 tab 切换 ...
- Vue组件封装的过程
Vue组件封装的过程 vue组件的定义 组件(Component)是Vue.js最强大的功能之一 组件可以扩展HTML元素,封装可重用代码 在较高层面上,组件是自定义元素,Vue.js的编译器为他添加 ...
- Vue 组件封装、组件传值、数据修改
Vue 组件封装 封装的意义 当一个页面元素过多或者一个组件在多个页面都会被使用,就可以进行组件封装,可以对单个页面解耦,增加代码的可读性,并且多次使用的组件方便修改,只用修改一个地方就能对用到这个组 ...
- Vue 组件封装之 Carousel 轮播图
Vue 组件封装之 Carousel 轮播图 一.Carousel 轮播图组件 二.使用案例 三.API 使用指南 四.源代码 一.Carousel 轮播图组件 组件说明: 实现无缝轮播. 效果展示: ...
最新文章
- java实现最长连续子序列_最长公共子序列 ||
- MySQL-数据库和表的基本操作
- C语言过河问题主函数,c,c++_C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因?,c,c++,算法 - phpStudy...
- 【学习笔记】MySQL 数据备份与恢复
- c语言文件所在的卷,C语言复习卷带答案.docx
- SpringBoot使用velocity模板引擎
- 数字调制2ASK误码率分析matlab实现
- 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景
- Spring Boot 学习系列(01)—从0到1,只需两分钟
- linux 系统性能分析常用命令
- 计算机毕业设计之微信小程序的点餐系统 网上订餐app的论文
- java web play_玩转Java Web应用开发:Play框架
- 图测1.0 在线地图测量与高清卫星图App 发布
- [转]	 全球最值得听的100首英文歌【空了 听下吧】
- 请正视抑郁症(附Zung氏抑郁自评量表(SDS))
- 理财U24 认股权证、可赎债、可转债、永续债、优先股 教材解读
- 木马是如何编写的(一)
- 中国联通沃云----弹性块存储使用说明
- 百万级数据连表查询优化
- python轮子下载教程