最近在做报表功能,筛选条件自动吸顶,并且表格表头也要自动吸顶
首先想到的就是vue的自定义指令(原谅我css学的不好,第一时间没想到position的 sticky属性),既然想到使用自定义指令,那就想想需要实现的思路,实际很简单:
- import type { Directive, App } from 'vue';
-
- const stickyDirective: Directive = {
- mounted(el, binding) {
- const scrollParent = binding.value.scrollParent
- ? document.querySelector(binding.value.scrollParent)
- : document.body;
- el.parent = scrollParent;
- const parent = document.querySelector(binding.value.parent);
- el.scrollParent = scrollParent;
- el.parent = parent;
- const elHeight = el.getBoundingClientRect().height;
- const elWidth = el.getBoundingClientRect().width;
- el.height = elHeight;
- el.width = elWidth;
- },
- updated(el, binding) {
- const elTop = el.getBoundingClientRect().top;
- // on函数,是封装的监听事件,根据自己的需求适当修改即可
- on(el.scrollParent, 'scroll', (): void => {
- const scrollTop = el.scrollParent.pageYOffset || el.scrollParent.scrollTop;
- if (scrollTop > elTop - (binding.value.top || 0)) {
- el.style.position = 'fixed';
- el.style.zIndex = '9';
- el.style.top = (binding.value.top || 0) + 'px';
- el.style.width = el.width + 'px';
- el.style.boxShadow =
- '0px 9px 28px 8px rgba(0,0,0,0.05), 0px 6px 16px 0px rgba(0,0,0,0.08), 0px 3px 6px -4px rgba(0,0,0,0.12)';
- // 因为当前节点脱离文档流,导致吸顶的瞬间,节点之后的内筒瞬间向上移动当前节点高度,有一种跳跃感
- // 所以在此设置此节点父级paddingtop
- el.parent.style.paddingTop = el.height + 'px';
- } else {
- el.style.position = 'static';
- el.style.boxShadow = 'none';
- el.parent.style.paddingTop = 0;
- }
- });
- },
到此基本就实现了一个简单的节点吸顶的功能了。
现在着手实现表格表头的吸顶功能,在这里说下,我的项目中使用的是vben,一个基于antd vue的开箱即用的项目,本质上还是antd vue。
至于表格表头吸顶项目,肯定第一时间去看antd的官方文档Table,看到了这个sticky属性(这时才想起来position的这个属性)。

可以去看下antd vue Table的源码,并不复杂,实际上就是通过position:sticky实现表头的吸顶。
既然知道怎么使用了,直接用在Table的组件上就好,满心欣喜的把sticky属性用上了,结果并没有起作用,第一时间有些懵逼,难道是vben里antd的版本过低,属性不存在,就去看了代码,发现antd版本是3.*是支持sticky属性的,看到这就更懵逼了,明明支持的属性却无法实现需要的功能,那就只能研究下position:sticky这个css属性了,毕竟归根结底是通过它实现的功能。
然后就在mdn,看到了这句话:

这两句话什么意思,就是需要吸顶的节点的父级,包含其祖先直到根节点,不能使用 overflow的hidden, scroll, auto, 或 overlay这四个属性,如果使用,sticky将失效。
以上就是项目中遇到的一些问题,在这做一个记录,不喜勿喷。