ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue2+ElementUI中el-table自定义样式:消除右侧和下方边框全攻略

Vue2+ElementUI中el-table自定义样式:消除右侧和下方边框全攻略 搞vue2后台项目的兄弟十有八九都跟elementUI的el-table较过劲。默认的表格样式其实不算难看但一到定制化界面就露怯右侧和下方总是莫名其妙多一条细线跟设计稿怎么都对不上。这篇文章就干一件事——把vue2 elementUI的el-table自定义样式这整套逻辑讲透重点解决“怎么把右侧和下方的边框去掉”顺带把滚动条宽度、固定列残留线、自动计算表格高度这些高频踩坑点一起收拾了。适合正在用vue2 elementUI做后台管理系统、天天被表格样式折磨的前端同学。1. 先搞清楚右侧和下方那条边框到底是谁画的1.1 默认边框从哪来很多人一上来就写CSS去覆盖结果怎么都去不掉就是因为没搞明白边框的出处。el-table渲染出来之后本质上是一个div包着一层table的结构。如果你没有给它加border属性它默认显示的是表头下方一条线、每一行数据下方一条线颜色统一是#EBEEF51px solid。这一条线来自表头th和单元格td的border-bottom。如果你在el-table上加了border属性情况就不一样了。此时element会追加一个.el-table--border的类然后每个单元格的border-right、border-bottom都会被强制加上。换句话说右侧那一列列竖线绝大多数情况下就是单元格td的border-right拼出来的下方那条线是每一行td的border-bottom拼出来的。所以第一条经验要消除右侧边框核心打击目标是th、td上的border-right要消除下方边框核心打击目标是td上的border-bottom。这是最底层、跑不掉的两个来源。1.2 不只是单元格伪元素和固定列才是漏网之鱼只处理td和th还不够。el-table在很多场景下会通过伪元素::before和::after来画线。比如.el-table::before默认有1px的底部边框如果你只把单元格的边框清掉表格最底部依然会残留一条横线很多人以为是自己没写对其实那条线根本不是td的边框。再看固定列。当表格设置fixedright之后element会在右侧生成一个.el-table__fixed-right浮层这个浮层自带border-left。你不处理它右侧固定列边缘就永远有一道竖线。左侧固定列同理自带border-right。再把范围扩大一点.el-table__header-wrapper、.el-table__body-wrapper这些滚动容器在部分版本的element-ui里也带border或background样式。展开行功能的.el-table__expanded-cell同样有独立的边框和背景。把el-table拆开看边框的来源至少分三类单元格th/td的border、根元素和子容器的伪元素边框、固定列容器的边框。这三类缺一不可只覆盖其中一两个都会留下“漏网之鱼”。1.3 三张“来源定位表”帮你精准排查我把el-table的边框来源整理成一张表后面做样式覆盖的时候对着表从上往下找基本一抓一个准边框位置实际来源命中选择器表体右侧竖线td和th的border-right加border属性后出现th.el-table__cell / td.el-table__cell表体下方横线td和th的border-bottomtd.el-table__cell表格底部残留线.el-table的::before / ::after伪元素.el-table::before / .el-table::after右侧固定列边界线.el-table__fixed-right的border-left.el-table__fixed-right左侧固定列边界线.el-table__fixed-left的border-right.el-table__fixed-left展开行底部边框.el-table__expanded-cell的border-bottom.el-table__expanded-cell这张表是我实际排查时的备忘。每次测试反馈“这里还有一条线”我就按这个表从上往下找一遍基本三分钟内定位。后面所有处理方案本质上都是针对这张表里的某些选择器动手。2. 自定义样式方案选型为什么scoped里直接写没有效果2.1 三种写法的取舍vue2项目里很多人第一反应是在自己组件的style标签里写.el-table td { border-right: none; }然后发现根本没反应。原因很简单style标签加了scoped之后vue会给当前组件模板里的标签加一个data-v-xxx属性选择器编译出来变成了.el-table td[data-v-xxx]。但el-table内部的th、td是element组件内部渲染出来的节点并不带你这个组件自定义的data-v属性选择器匹配不上。那怎么办三种思路第一去掉scoped写一段全局样式。可行但会污染整个项目的所有el-table。除非你用非常严格的class命名把自己限制在一个局部容器内否则不推荐。第二用::v-deep也就是vue2里的深度作用选择器旧版写法也叫/deep/。它编译后会把选择器改写成后代选择器比如.no-border-table[data-v-xxx] .el-table td这样就能穿透scoped限制命中内部元素。这是日常开发中最常用的方案。第三单独写一个非scoped的样式文件在组件里import。本质上是第二种的变体但文件独立适合沉淀通用样式。我在vue2项目里推荐第二或第三种更推荐第三种el-table的样式覆盖通常不是一次性的后面可能会改滚动条、改hover、改斑马纹、改展开行单独维护一个table样式文件会清爽很多。2.2 加class命名空间才是明智的做法有人直接覆盖全局的.el-table td样式把整个项目的表格边框全部去掉。结果另一个页面需要带边框的表格又要再覆盖回来来回折腾极易互相打架。我的习惯是每一张需要定制样式的表格都加一个自定义class比如el-table classless-border-table :datatableData/el-table样式里以这个class为命名空间去覆盖.less-border-table { ::v-deep th.el-table__cell, ::v-deep td.el-table__cell { border-right: none; } }这样既不污染其他表格又能利用::v-deep直接命中内部元素。这种“自定义class 深度选择器”的组合不只适用于el-table所有需要深度定制第三方组件样式的场景都能套用。比如dialog、select、date-picker用这套思路都很顺手。3. 消除右侧和下方边框的完整实操直接抄代码3.1 最常用的“去竖线保留横线”方案大多数后台表格的设计需求是“去掉单元格之间的竖线保留行与行之间的横线”这样视觉上更干净又不至于行都分不清。先给el-table加一个自定义class我统一用no-vertical-borderel-table classno-vertical-border :datatableData/el-tablescss.no-vertical-border { ::v-deep th.el-table__cell { border-right: none; } ::v-deep td.el-table__cell { border-right: none; } }注意我这里选用了.el-table__cell。element-ui 2.x里表头th和表体td上都挂了这个类写一条规则就能同时覆盖表头和表体优先级也够不用再单独加行选择器。实测在element-ui 2.15.x下非常稳定。3.2 “彻底无边框”方案横线竖线一次清干净如果你要的是完全融入背景的表格把竖线、横线、表头线全部抹掉.no-border-all { ::v-deep th.el-table__cell, ::v-deep td.el-table__cell { border: none; } ::v-deep .el-table__footer-wrapper td.el-table__cell { border: none; } ::v-deep .el-table__fixed-left, ::v-deep .el-table__fixed-right { border: none; } }这里特意加上了footer-wrapper因为合计行、底部统计行也有独立的边框不处理的话表格底部还是会冒出一条线。另外固定列容器的border也在这一步顺手清掉。3.3 根治底部残留线别忘了伪元素单元格边框清干净之后如果表格最底部还有一条横线百分之九十是伪元素。针对它单独开一枪.no-border-all { ::v-deep.el-table::before, ::v-deep.el-table::after { display: none; } }这里有个写法细节::v-deep后面既可以空格接选择器也可以直接连写。在scss里我推荐连写比如::v-deep.el-table::before编译更可控。如果你发现覆盖不彻底加个!important也不丢人毕竟这是对第三方组件样式的强制修正只要不影响全局就好。3.4 固定列边界线一条隐藏的竖线表格启用了fixedright或fixedleft时处理完以上所有步骤固定列旁边可能还有一道竖线。这道线来自固定列浮层本身的border-left或border-right.no-border-all { ::v-deep .el-table__fixed-right { border-left: none; } ::v-deep .el-table__fixed-left { border-right: none; } }但这里要提醒一句固定列本身就是用来区分可视区和滚动区的把边界线去掉后滚动时内容会直接贴着固定列切换视觉上有辨识压力。如果设计师坚持要无边框可以顺手在固定列内容区加一个轻微的box-shadow模拟一条影子分割线.no-border-all { ::v-deep .el-table__fixed-right { box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.06); } }用户看着仍有一条“物理边界”但不再是一根死板的边框线。这个小细节在定制化后台里很加分。3.5 滚动条宽度一并调节让无边框更彻底去掉边框后下方如果有横向滚动条默认的粗滚动条会显得很突兀。el-table的滚动条也是可以自定义的.no-border-all { ::v-deep .el-table__body-wrapper::-webkit-scrollbar { height: 6px; width: 6px; } ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 3px; } ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track { background: transparent; } }height控制横向滚动条厚度width控制纵向滚动条宽度。如果你用的是el-table自带的纵向滚动同样生效。webkit前缀在Chrome、Edge、微信内置浏览器里都稳定不需要额外处理兼容。4. 工程化落地经验vue2项目里如何优雅组织这些样式4.1 把el-table的覆盖样式沉淀成一个独立文件真正在vue2项目里做工程化我不会把这些样式散落在各个组件的style里而是建一个src/styles/element-table.scss专门放el-table的样式覆盖。文件内部按class命名空间划分区块比如.less-border-table、.no-border-table、.table-with-shadow。谁要用直接在组件里import /styles/element-table.scss;或者在main.js里全局引入。这样维护成本极低。尤其是多个页面都需要做无边框表格时不会出现每个文件复制同一份deep样式的情况。后面产品说“这种表格样式要微调”你只需要改一个文件所有页面同步生效。4.2 配合自动计算表格宽高无边框表格的灵魂搭档热搜里经常有人问“el-table自动计算列表的宽高”。这其实是后台系统里的标配需求表格区域自适应视口高度避免表格把页面撑出滚动条。通常做法是在data里维护tableHeight在mounted和updated里计算data() { return { tableHeight: 400 }; }, mounted() { this.computeTableHeight(); window.addEventListener(resize, this.computeTableHeight); }, updated() { this.computeTableHeight(); }, beforeDestroy() { window.removeEventListener(resize, this.computeTableHeight); }, methods: { computeTableHeight() { const el this.$refs.tableWrap; if (!el) return; this.tableHeight el.clientHeight - 80; } }模板里div reftableWrap classtable-wrap el-table reftable classno-border-all :heighttableHeight :datalist/el-table /div注意height要绑定在el-table的height属性上不要直接给el-table写CSS高度。ey-el-table内部需要知道容器高度来计算固定列和滚动区域纯CSS高度会导致一系列样式错乱。这个坑我踩过后来全面改成height属性绑定。updated生命周期里重新计算高度也很关键因为数据更新后行高会变化比如展开行或删除行不及时重算可能会出现一小段留白。4.3 hbuilderx和常规vue2工程里的兼容差异有朋友是在hbuilderx里创建vue2项目把elementUI搭在手写脚手架里的。其实这类工程的编译方式跟vue-cli基本一致::v-deep写法都能正常编译不用特意改。真正需要检查的是sass依赖是否装全。如果项目里用的是scss需要npm i sass sass-loader -D没有sass的话也可以直接用CSS原生写法把::v-deep换成/deep/或者干脆在全局样式文件里写只是嵌套层级会难维护一点。只要是纯Web工程无论是vue-cli、vitevue2还是hbuilderx的Web项目前面这些方案都通用。4.4 结合CSS变量做主题切换无边框样式可以跟elementUI的主题变量结合起来。比如看板类项目要求表格背景透明、表头半透明底色就不应该把颜色写死.no-border-table { ::v-deep .el-table__header th { background: var(--table-header-bg, rgba(255, 255, 255, 0.8)); } ::v-deep .el-table__row td { background: var(--table-body-bg, rgba(255, 255, 255, 0.5)); } }后续做深色主题、浅色主题切换时只需要在html根节点切一个theme类就能控制这些变量。这是无边框表格之外的进阶玩法但在一些对视觉效果要求高的后台里特别实用。5. 常见问题排查实录样式覆盖为什么老翻车5.1 样式完全不生效先查三个地方第一选择器优先级。element自身的样式写在element-ui的样式表里你的样式如果写得太浅就会被它盖过去。解决方式是提高权重比如写成.no-border-table ::v-deep .el-table__row td.el-table__cell { border-right: none !important; }加!important是最后手段但对抗第三方组件时只要不影响全局用一点也无妨。第二scoped失效。如果::v-deep编译后还是没命中先检查sass版本和vue-loader版本。vue2 elementUI的常规组合里::v-deep都能用。如果项目里是特别老的vue-loader 14建议试/deep/。注意这两种写法不要混在同一个选择器里。第三样式被同名类覆盖。排查方法很简单浏览器开发者工具里选中目标td元素看右侧Border那一栏往上翻是谁给它设置的border把那个选择器复制出来以它为基准再覆盖基本都能解决。5.2 固定列右侧的边框总是清不掉这个太常见了。很多朋友把td、th、伪元素全处理了固定列那道竖线还在。原因是.el-table__fixed-right浮层本身的border-left才是关键。另外固定列区域里也可能有一套独立的表头容器需要一起处理.no-border-table { ::v-deep .el-table__fixed-right th.el-table__cell, ::v-deep .el-table__fixed-right td.el-table__cell { border: none; } }5.3 hover高亮块被裁切或者不对齐去掉单元格边框后hover行的高亮背景有时会出现锯齿或错位。通常是因为el-table的行背景写在tr上或者由单元格背景拼出来的。如果出现背景断裂先把单元格背景设为透明再在tr上设置背景.no-border-table { ::v-deep .el-table__body tr:hover td.el-table__cell { background: transparent; } ::v-deep .el-table__body tr:hover { background: #f5f7fa; } }hover背景尽量放在tr上因为tr覆盖整行宽度不容易出现中间断线。5.4 展开行样式断裂怎么处理用了展开行功能后展开出来的内容区实际上是一个新的tr它往往自带背景和边框。处理方式.no-border-table { ::v-deep .el-table__expanded-cell { border-right: none; border-bottom: none; background: transparent; } }同时注意展开行默认背景是#fafafa如果要去掉就设为transparent方便你自定义展开区域的内容样式。5.5 sortable拖动排序、全选回显对样式的联动影响“el-table sortable拖动 拓展行”和“elementui表格选择框回显然后全选错误”这类热搜虽然更多是交互问题但复盘下来跟样式也有联动。比如拖动排序后行顺序变了如果行高不一致会出现边框或背景错位。此时可以强制触发一次表格重新布局this.$nextTick(() { this.$refs.table.doLayout(); });doLayout是el-table内置方法专门用来重算表格布局处理拖动、显隐、固定列更新后的样式错乱非常管用。凡是改了数据、选了全选、展开行、拖了排序发现布局不太对先doLayout一下大多数问题都能消解。5.6 表格数据不满一屏时底部多出空白还有一种特殊情况当表格数据不满一页时底部会留下一片空白的body区域。这个区域虽然没有数据行但.el-table__body-wrapper的高度还在容易让人误以为边框没去掉。此时可以给表格设置height或max-height让空余区域被剪掉。或者调整body-wrapper的overflow-x.no-border-table { ::v-deep .el-table__body-wrapper { overflow-x: hidden; } }但注意如果表格有横向滚动需求不要轻易改overflow-x。更稳妥的做法是控制height属性让它刚好等于内容高度这就要结合第4.2节的自动计算宽高方案一起使用。6. 一些实操体会与拓展建议先说说我自己的实测经验。标题里“自定义样式及消除右侧和下方的边框”实际上分两种诉求一种只想去掉竖线、保留横线的分割感另一种是彻底无边框让表格完全融入设计。这两种我后来在工程中都维护成了独立class比如.without-vertical-border和.without-all-border用的时候各取所需。千万不要一个class撸到底否则想找回横线时又得重写。还有一个体会不要过度依赖!important。我见过有人写了一大堆!important把element样式强行踩下去结果后面产品说“加回竖线”一行样式改了三个文件才搞定。靠谱的做法是先把el-table的边框来源逐一排查清楚再以自定义class为命名空间去精准处理。如果项目里用了scss把这类样式沉淀到独立文件里后面不管怎么改都只是动一个文件的几行规则。最后再分享一个小技巧如果只想让表格底部那条线消失但完全不想动横线和竖线只需要针对.el-table::before这一个伪元素动手::v-deep .el-table::before { display: none; }这是“只消除下方边框”的最小改动方案实测在element-ui 2.15.x下有效。如果你用的版本不同打开开发者工具选中底板容器看伪元素是否存在再决定写不写这条规则。OK以上就是在vue2里给el-table做自定义样式、消除右侧和下方边框的全部经验按这套思路来基本能覆盖九成以上的定制需求。
返回列表