文章目录

  • 前言
  • 效果展示
  • 正文
    • 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的控制动画的属性:transitionenter-active-classleave-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会影响动画的执行,传入的transitionenter-active-classleave-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相关推荐

  1. Vue 组件封装之 ScrollView 上拉加载更多

    Vue 组件封装之 ScrollView 上拉加载更多 一.ScrollView 上拉加载更多 二.使用案例 三.API 使用指南 四.源代码 一.ScrollView 上拉加载更多 组件说明: 实现 ...

  2. Vue 组件封装之 Questionnaire 问卷调查

    Vue 组件封装之 Questionnaire 问卷调查 前言 一.Questionnaire 组件 二.使用案例 三.API 使用指南 四.源代码 前言 问卷调查表也是目前前端比较常见的开发项目,目 ...

  3. Vue 组件封装之 Content 列表(处理多行输入框 textarea)

    Vue 组件封装之 Content 列表 一.Content 列表 二.使用案例 三.API 使用指南 四.源代码 一.Content 列表 组件说明: 实现 Content 列表布局排版. 效果展示 ...

  4. Vue 组件封装之 List 列表

    Vue 组件封装之 List 列表 一.List 列表 二.使用案例 三.API 使用指南 四.源代码 一.List 列表 组件说明: 实现 List 列表布局排版. 效果展示: 实现的功能: 在一个 ...

  5. Vue 组件封装之 Search 搜索

    Vue 组件封装之 Search 搜索 一.Search 组件 二.使用案例 三.API 使用指南 四.源代码 一.Search 组件 组件说明: 实现搜索功能. 效果展示: input 输入框背景铺 ...

  6. Vue组件封装,(面试回答)

    在我用vue开发项目的时候,一般我都会用到组件封装,采用组件化的思想进行项目开发,我在搭建一个项目的时候,就会创建一个views目录和一个commen目录和一个feature目录,views目录中放页 ...

  7. Vue 组件封装之 Tab 切换

    Vue 组件封装之 tab 切换 一.Tab 切换组件 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tab 切换组件 组件说明: 实现 tab 切换. 效果展示: 实现 tab 切换 ...

  8. Vue组件封装的过程

    Vue组件封装的过程 vue组件的定义 组件(Component)是Vue.js最强大的功能之一 组件可以扩展HTML元素,封装可重用代码 在较高层面上,组件是自定义元素,Vue.js的编译器为他添加 ...

  9. Vue 组件封装、组件传值、数据修改

    Vue 组件封装 封装的意义 当一个页面元素过多或者一个组件在多个页面都会被使用,就可以进行组件封装,可以对单个页面解耦,增加代码的可读性,并且多次使用的组件方便修改,只用修改一个地方就能对用到这个组 ...

  10. Vue 组件封装之 Carousel 轮播图

    Vue 组件封装之 Carousel 轮播图 一.Carousel 轮播图组件 二.使用案例 三.API 使用指南 四.源代码 一.Carousel 轮播图组件 组件说明: 实现无缝轮播. 效果展示: ...

最新文章

  1. java实现最长连续子序列_最长公共子序列 ||
  2. MySQL-数据库和表的基本操作
  3. C语言过河问题主函数,c,c++_C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因?,c,c++,算法 - phpStudy...
  4. 【学习笔记】MySQL 数据备份与恢复
  5. c语言文件所在的卷,C语言复习卷带答案.docx
  6. SpringBoot使用velocity模板引擎
  7. 数字调制2ASK误码率分析matlab实现
  8. 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景
  9. Spring Boot 学习系列(01)—从0到1,只需两分钟
  10. linux 系统性能分析常用命令
  11. 计算机毕业设计之微信小程序的点餐系统 网上订餐app的论文
  12. java web play_玩转Java Web应用开发:Play框架
  13. 图测1.0 在线地图测量与高清卫星图App 发布
  14. [转] 全球最值得听的100首英文歌【空了 听下吧】
  15. 请正视抑郁症(附Zung氏抑郁自评量表(SDS))
  16. 理财U24 认股权证、可赎债、可转债、永续债、优先股 教材解读
  17. 木马是如何编写的(一)
  18. 中国联通沃云----弹性块存储使用说明
  19. 百万级数据连表查询优化
  20. python轮子下载教程

热门文章

  1. Java 中ArrayList中的重复数据
  2. GitHub爆款项目,去马赛克软件Depix使用
  3. 而洗洁精膜会有效地保持玻璃2小时内不结霜
  4. oracle ORA-28002:the password will expire within 7 days 解决方法
  5. 企业网配置必备技术NAT,3张图理清
  6. 学完这个你就成为excel高手了!(Delphi对Excel的所有操作)逐个试试!
  7. FTP服务器架设--架设篇
  8. EAS 从查询分析器导出表数据的插入语句
  9. SecureCRT登录会话密码解密
  10. Apache和Spring提供的StopWatch执行时间监视器