如何用element-ui实现表格边框动态切换及防抖功能的优化?

2026-03-31 17:511阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1845个文字,预计阅读时间需要8分钟。

如何用element-ui实现表格边框动态切换及防抖功能的优化?

目录+需求+实现过程+解决滑动+滑动原因+解决滑动的实现过程+再优化+后续+固定列表+需求+需求是这样的:+先前的需求,要求表格按UI设计图来,表格无边框。+新的需求,要求能支持表格。

目录
  • 需求
  • 实现过程
  • 解决抖动
    • 抖动原因
    • 解决抖动的实现过程
  • 再优化
    • 后记
      • 固定列

    需求

    需求是这样的:

    • 先前的需求,要求表格按UI设计图来,表格无边框。
    • 新来的需求,要求能支持表格列宽的能够支持拖动。

    按照官网,table组件的border属性,设置为true时可以显示边框。有了边框才能拖。

    但是显示了边框,与之前的需求相悖。同时,既然显示边框有属性border支持,那么动态的更新border的值,应该就可以实现显示表格边框的动态切换。

    基于此思路,采用比较折中的办法:

    • 默认状态下不显示边框
    • 当鼠标移动到表格头部时,显示边框,这个时候允许拖动。

    鼠标移动时,通过监控鼠标事件,动态的更新border属性的值,进而动态切换边框的显示。

    实现过程

    Vue组件中data属性中增加一个showBorder, 默认值false, 并将其绑定到table组件border属性上

    <el-table :data="tableData" :border="showBorder" @selection-change="handleSelectionChange" > ...

    export default { data () { return { showBorder: false } } } ...

    添加鼠标事件、更新showBorder的值

    ... methods: { // 要在表格渲染出来后再加 addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } }, updataTableBorder (value) { this.showBorder = value } } ...

    到这里,功能已经实现了,当鼠标移动到表头时,边框显示,然后就可以拖动列。鼠标从表头移开,切换的无边框状态。

    • But

    如果只是这么操作,会发现切换时,表格会抖动。体验感非常的不好。

    解决抖动

    抖动原因

    之所以会抖动,是因为不显示边框时,boder的width值为0,在切换到显示边框时,边框有了实际的宽度,会占位置,导致表格相对无边框时出现位置偏移。

    如何让边框切换时,不抖动呢?

    方案:

    如何用element-ui实现表格边框动态切换及防抖功能的优化?

    先给表格加上边框,

    • 当不显示边框时,将边框的颜色设置为透明,保留其原有的像素占位。
    • 当显示边框时,只需要将颜色值更新回来,就可以了。

    解决抖动的实现过程

    对比切换前后的表格样式,发现边框样式,涉及到以下三个地方。

    表格最外围的div,控制表格最外围的边框,对应的边框border-top, border-left表头单元格,控制表头单元格的边框, 控制表头单元格的boder-bottom,border-right行单元格, 控制单元格的边框, 控制行单元格的boder-bottom,border-right

    另外,element-ui的table组件,有三个属性,刚好可以控制表格、表头单元格和所有单元格的样式。分别是

    • style
    • header-cell-style
    • cell-style

    cell-style属性时配置所有单元格的样式(包括表头),header-cell-style只控制表头的单元格样式。如果你没有另外配置header-cell-style,完全可以用cell-style来控制所有单元格的边框。

    那么,给style、header-cell-style、cell-style属性,分别绑定tableStyle、headerCellStyle、cellStyle等三个变量,动态的更新这三个值,依照Vue的响应式原理,对应的style、header-cell-style、cell-style属性值将会随之改变。

    <el-table :data="tableData" :border="showBorder" :style="tableStyle" :header-cell-style="headerCellStyle" :cell-style="cellStyle" @selection-change="handleSelectionChange" >

    const noBordertyle = '1px solid transparent' const borderStyle = '1px solid #EBEEF5' export default { data () { return { showBorder: false, // 表格样式 tableStyle: { borderTop: noBordertyle, borderLeft: noBordertyle }, // 表头样式 headerCellStyle: { background: 'rgba(42,113,255,0.03)', color: '#000000', borderBottom: noBordertyle, borderRight: noBordertyle }, // 单元格样式 cellStyle: { borderBottom: noBordertyle, borderRight: noBordertyle } } }, methods: { // 要在表格渲染出来后再加 addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } }, updataTableBorder (open) { this.showBorder = open const border = open ? borderStyle : noBordertyle this.tableStyle.borderTop = border this.tableStyle.borderLeft = border this.headerCellStyle.borderBottom = border this.headerCellStyle.borderRight = border this.cellStyle.borderBottom = border this.cellStyle.borderRight = border } } }

    这样就解决掉边框切换时的抖动问题啦。

    再优化

    问题虽然得到了解决,但是,通常在项目中,会有很多地方用到表格,表格的风格一般都是一致的。

    如果按上述过程直接用,那么在每个使用表格的组件中,都要加入处理这些代码。处理维护起来,那是相当的繁琐。

    如果能把这些处理过程,放到一个地方单独维护,那就舒服多了。

    想到Vue的 mixin 混入了吧。

    • 新建一个混入文件,tableMixin.js,还是上面的代码。
    • 在使用表格的组件中,导入tableMixin并在混入选项中加入。

    import mixin from ''./mixins/tableMixin export default { ... mixins: [mixin] }

    完!!!

    后记

    按之前的处理完成后,表格确实不抖动了。但仔细观察后发现,位于表格最后一列的操作列,左边的边框没显示。而是只是差了1个像素没显示。

    反复检查单元格的边框样式,都是正常的。也就是正常情况下应该会显示,而实际就是没有。百思不得其解。

    转天再看这个问题,发现最后的操作列使用了fixed属性,为固定列。也就是当使用横向滚动条拖动时,最后的操作列位置是不变的。

    固定列

    仔细检查固定列,查看DOM结构,发现多了一个 el-table__fixed-right 的div,样式使用了绝对定位,并且在内联样式中设置了宽度width。而且这家节点刚好对应右侧的操作列。

    那么是不是这个div,覆盖在本该显示的边框元素之上,由于我用非常规手段,修改了边框,导致这个绝对定位的元素,width值已不准确,进而边框被覆盖。

    手动调整固定列的列宽,去掉1个像素。果然边框出现了。

    既然找到症结,解决问题也就简单了。在addListener方法中,把这个div的宽度减1就OK了。

    addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } const fixedRightNode = this.$el.querySelector('.el-table__fixed-right') if (fixedRightNode) { const width = fixedRightNode.style.width fixedRightNode.style.width = width ? (parseInt(width) - 1) + 'px' : width } },

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

    本文共计1845个文字,预计阅读时间需要8分钟。

    如何用element-ui实现表格边框动态切换及防抖功能的优化?

    目录+需求+实现过程+解决滑动+滑动原因+解决滑动的实现过程+再优化+后续+固定列表+需求+需求是这样的:+先前的需求,要求表格按UI设计图来,表格无边框。+新的需求,要求能支持表格。

    目录
    • 需求
    • 实现过程
    • 解决抖动
      • 抖动原因
      • 解决抖动的实现过程
    • 再优化
      • 后记
        • 固定列

      需求

      需求是这样的:

      • 先前的需求,要求表格按UI设计图来,表格无边框。
      • 新来的需求,要求能支持表格列宽的能够支持拖动。

      按照官网,table组件的border属性,设置为true时可以显示边框。有了边框才能拖。

      但是显示了边框,与之前的需求相悖。同时,既然显示边框有属性border支持,那么动态的更新border的值,应该就可以实现显示表格边框的动态切换。

      基于此思路,采用比较折中的办法:

      • 默认状态下不显示边框
      • 当鼠标移动到表格头部时,显示边框,这个时候允许拖动。

      鼠标移动时,通过监控鼠标事件,动态的更新border属性的值,进而动态切换边框的显示。

      实现过程

      Vue组件中data属性中增加一个showBorder, 默认值false, 并将其绑定到table组件border属性上

      <el-table :data="tableData" :border="showBorder" @selection-change="handleSelectionChange" > ...

      export default { data () { return { showBorder: false } } } ...

      添加鼠标事件、更新showBorder的值

      ... methods: { // 要在表格渲染出来后再加 addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } }, updataTableBorder (value) { this.showBorder = value } } ...

      到这里,功能已经实现了,当鼠标移动到表头时,边框显示,然后就可以拖动列。鼠标从表头移开,切换的无边框状态。

      • But

      如果只是这么操作,会发现切换时,表格会抖动。体验感非常的不好。

      解决抖动

      抖动原因

      之所以会抖动,是因为不显示边框时,boder的width值为0,在切换到显示边框时,边框有了实际的宽度,会占位置,导致表格相对无边框时出现位置偏移。

      如何让边框切换时,不抖动呢?

      方案:

      如何用element-ui实现表格边框动态切换及防抖功能的优化?

      先给表格加上边框,

      • 当不显示边框时,将边框的颜色设置为透明,保留其原有的像素占位。
      • 当显示边框时,只需要将颜色值更新回来,就可以了。

      解决抖动的实现过程

      对比切换前后的表格样式,发现边框样式,涉及到以下三个地方。

      表格最外围的div,控制表格最外围的边框,对应的边框border-top, border-left表头单元格,控制表头单元格的边框, 控制表头单元格的boder-bottom,border-right行单元格, 控制单元格的边框, 控制行单元格的boder-bottom,border-right

      另外,element-ui的table组件,有三个属性,刚好可以控制表格、表头单元格和所有单元格的样式。分别是

      • style
      • header-cell-style
      • cell-style

      cell-style属性时配置所有单元格的样式(包括表头),header-cell-style只控制表头的单元格样式。如果你没有另外配置header-cell-style,完全可以用cell-style来控制所有单元格的边框。

      那么,给style、header-cell-style、cell-style属性,分别绑定tableStyle、headerCellStyle、cellStyle等三个变量,动态的更新这三个值,依照Vue的响应式原理,对应的style、header-cell-style、cell-style属性值将会随之改变。

      <el-table :data="tableData" :border="showBorder" :style="tableStyle" :header-cell-style="headerCellStyle" :cell-style="cellStyle" @selection-change="handleSelectionChange" >

      const noBordertyle = '1px solid transparent' const borderStyle = '1px solid #EBEEF5' export default { data () { return { showBorder: false, // 表格样式 tableStyle: { borderTop: noBordertyle, borderLeft: noBordertyle }, // 表头样式 headerCellStyle: { background: 'rgba(42,113,255,0.03)', color: '#000000', borderBottom: noBordertyle, borderRight: noBordertyle }, // 单元格样式 cellStyle: { borderBottom: noBordertyle, borderRight: noBordertyle } } }, methods: { // 要在表格渲染出来后再加 addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } }, updataTableBorder (open) { this.showBorder = open const border = open ? borderStyle : noBordertyle this.tableStyle.borderTop = border this.tableStyle.borderLeft = border this.headerCellStyle.borderBottom = border this.headerCellStyle.borderRight = border this.cellStyle.borderBottom = border this.cellStyle.borderRight = border } } }

      这样就解决掉边框切换时的抖动问题啦。

      再优化

      问题虽然得到了解决,但是,通常在项目中,会有很多地方用到表格,表格的风格一般都是一致的。

      如果按上述过程直接用,那么在每个使用表格的组件中,都要加入处理这些代码。处理维护起来,那是相当的繁琐。

      如果能把这些处理过程,放到一个地方单独维护,那就舒服多了。

      想到Vue的 mixin 混入了吧。

      • 新建一个混入文件,tableMixin.js,还是上面的代码。
      • 在使用表格的组件中,导入tableMixin并在混入选项中加入。

      import mixin from ''./mixins/tableMixin export default { ... mixins: [mixin] }

      完!!!

      后记

      按之前的处理完成后,表格确实不抖动了。但仔细观察后发现,位于表格最后一列的操作列,左边的边框没显示。而是只是差了1个像素没显示。

      反复检查单元格的边框样式,都是正常的。也就是正常情况下应该会显示,而实际就是没有。百思不得其解。

      转天再看这个问题,发现最后的操作列使用了fixed属性,为固定列。也就是当使用横向滚动条拖动时,最后的操作列位置是不变的。

      固定列

      仔细检查固定列,查看DOM结构,发现多了一个 el-table__fixed-right 的div,样式使用了绝对定位,并且在内联样式中设置了宽度width。而且这家节点刚好对应右侧的操作列。

      那么是不是这个div,覆盖在本该显示的边框元素之上,由于我用非常规手段,修改了边框,导致这个绝对定位的元素,width值已不准确,进而边框被覆盖。

      手动调整固定列的列宽,去掉1个像素。果然边框出现了。

      既然找到症结,解决问题也就简单了。在addListener方法中,把这个div的宽度减1就OK了。

      addListener () { const tabHeader = this.$el.querySelector('.el-table__header-wrapper') if (tabHeader) { tabHeader.onmouseenter = this.updataTableBorder.bind(this, true) tabHeader.onmouseleave= this.updataTableBorder.bind(this, false) } const fixedRightNode = this.$el.querySelector('.el-table__fixed-right') if (fixedRightNode) { const width = fixedRightNode.style.width fixedRightNode.style.width = width ? (parseInt(width) - 1) + 'px' : width } },

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。