element-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,在切换到显示边框时,边框有了实际的宽度,会占位置,导致表格相对无边框时出现位置偏移。

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

方案:

先给表格加上边框,

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

解决抖动的实现过程

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

表格最外围的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
      }
    },

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 基于Vue+elementUI实现动态表单的校验功能(根据条件动态切换校验格式)

    前言 开发过程中遇到了一个需求,根据用户选择的联系方式,动态改变输入框的检验条件,并且整个表单是可以增加的 在线访问:动态表单校验 github(欢迎star): https://github.com/Mrblackant. .. 思考几个问题 1.整个表单是可新增的,所以要遍历生成: 2.联系方式(手机/座机)的切换,是要切换后边不同类型输入框还是只改变校验规则(本篇是动态改变校验规则) 实现 1.elementui的form表单实现校验的时候要给当前el-form-item加上prop属性,

  • 在vue+element ui框架里实现lodash的debounce防抖

    事情起因在:我使用element ui框架里的远程搜索框,在单选时,组件内部已经做了防抖,query是在一段时间内的字符串.但是在多选时,并没有做防抖,而是每输入一个字符都要向后台发一次请求,所以必须防抖,官方推荐使用lodash的debounce 在解决这个问题时,我遇到的坎儿主要有以下: 我首先在项目里用npm安装lodash,先全局安装,然后安装到项目 npm install -g lodash npm install --save lodash 安装后,我就在我要用防抖的组件里,引入lo

  • vue+elementui实现动态控制表格列的显示和隐藏

    vue+elementui(table,多选框)实现动态控制表格列的显示和隐藏,供大家参考,具体内容如下 imdex.vue <template>   <div>     <div>       <el-table :data="tableData" border style="width: 100%" ref="table">         <el-table-column prop=&q

  • vue+element-ui实现表格编辑的三种实现方式

    1.表格内部显示和编辑切换 这种方式就是利用两个标签显示隐藏来实现,我们这里用input和span,正常用span将数据显示,点击编辑时,将span隐藏,显示input进行编辑.选中当前行我们可以通过slot-scope中的index去实现,在控制显示隐藏的属性上绑定index就可以选中当前行了,如showEdit[index]. 页面结构代码: <el-table :data="tableData" tooltip-effect="dark" style=&

  • element-ui实现表格边框的动态切换并防抖

    目录 需求 实现过程 解决抖动 抖动原因 解决抖动的实现过程 再优化 后记 固定列 需求 需求是这样的: 先前的需求,要求表格按UI设计图来,表格无边框. 新来的需求,要求能支持表格列宽的能够支持拖动. 按照官网,table组件的border属性,设置为true时可以显示边框.有了边框才能拖. 但是显示了边框,与之前的需求相悖.同时,既然显示边框有属性border支持,那么动态的更新border的值,应该就可以实现显示表格边框的动态切换. 基于此思路,采用比较折中的办法: 默认状态下不显示边框

  • 详解vue2.0的Element UI的表格table列时间戳格式化

    这两天学习了vue2.0的Element UI的表格table列时间戳格式化,所以,今天添加一点小笔记. 表格属性 <el-table :data="tableData" v-loading.body="loading" border @selection-change="selectionChange" style="width: 100%"> <el-table-column prop="cre

  • vuejs+element UI table表格中实现禁用部分复选框的方法

    有时候我们构建这样带一列复选框的表格 然后希望根据条件禁用某个列表项的选择框,可以这样写 HTML: JS: 以上这篇vuejs+element UI table表格中实现禁用部分复选框的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • vue2.0 + element UI 中 el-table 数据导出Excel的方法

    1.安装相关依赖 主要是两个依赖 npm install --save xlsx file-saver 如果想详细看着两个插件使用,请移步github. https://github.com/SheetJS/js-xlsx https://github.com/eligrey/FileSaver.js 2.组件里头引入 import FileSaver from 'file-saver' import XLSX from 'xlsx' 3.组件methods里写一个方法 exportExcel

  • Element UI中table单元格合并的解决过程

    目录 引言 解决思路: 1.格式化后台返回的数据(根据实际数据格式处理) 2.在 data 中定义数据,需要合并几列就定义几个数组和索引 3.定义合并函数 4.table 组件属性 span-method 的单元格合并方法: 完整代码: 总结 引言 项目中遇到表格单元格合并的需求,在此记录整个解决过程. 项目使用的是 Element UI,表格使用的是 table 组件.Element UI 的 table 表格组件中对单元格进行合并,需要使用 table 组件的 span-method 属性.

  • element ui 表格动态列显示空白bug 修复方法

    在使用element ui框架进行项目开发的时候,表格的列是根据后台数据动态生成的,但是发现在列刷新的视乎,会出现表格完全空白,没有显示的情况,经过自己编写demo发现,在增加列的情况下表格正常,但是一旦表格列减少时就会出问题,对element底层代码进行调试发现,在node_modules/element-ui/lib/elementui.common.js 中的一个函数. removeColumn: function removeColumn(states, column) { var _c

  • 使用vue+element ui实现走马灯切换预览表格数据

    目录 1. 需求分析 2. 效果演示 3. 代码实现 3.1 table.json 3.2 HTML 代码 3.3 Script 代码 总结 1. 需求分析 有这样一个 json 文件(table.json),里面包含有多组需要展示的表格数据,需求就是需要将这些数据进行展示,并且能快速查看不同的数据,由于数据过多,不能一个表格一个表格的进行展示,所以找了一个比较合适的方法,就是通过走马灯将所有数据进行渲染,当切换走马灯时,再展示对应的数据. 2. 效果演示 3. 代码实现 3.1 table.j

  • Vue+Element ui 根据后台返回数据设置动态表头操作

    由于后端是多人开发,也没有规范数据格式,所有页面是我一个人开发,所以就会遇到同样的页面不同的返回数据格式问题. 一.根据element文档,利用prop属性绑定对应值,label绑定表头. html <el-table class="tb-edit" highlight-current-row :data="tableData" border style="width: 100%"> <template v-for="

  • vue+element UI实现树形表格

    本文实例为大家分享了vue+element UI实现树形表格的具体代码,供大家参考,具体内容如下 一.在component文件夹下新建如下treeTable文件夹,里面有2个文件: eval.js:将数据转换成树形数据 /** * @Author: jianglei * @Date: 2017-10-12 12:06:49 */ 'use strict' import Vue from 'vue' export default function treeToArray(data, expandA

  • 动态实现element ui的el-table某列数据不同样式的示例

    问题描述 在饿了么ui的框架中,输入数据el-form,输出数据el-table.有时候产品想让枯燥的表格来点动态的样式,比如不同的内容展示不同的样式,对于这个需求,其实方式有很多种,本文列举两种,以供参考. 实现方式一 效果图如下 代码如下 <template> <div id="app"> <!-- 需求:三国人物表格,要求不同的国别展示不同的颜色(魏国红色.蜀国黑色.吴国蓝色) --> <el-table :data="tabl

随机推荐