el-table 动态自适应宽度

el-table 动态自适应宽度

v-fit-columns

A Vue.js plugin that auto fits Element UI's el-table-column with cell content.
Vue.js 插件,可实现 Element UI el-table-column 宽度自适应内容,同时保持内容不换行。

Install

npm install v-fit-columns --save

Use

In app entry file:

import Vue from 'vue';
import Plugin from 'v-fit-columns';
Vue.use(Plugin);

In your component:

<el-table v-fit-columns>
  <el-table-column label="No." type="index" class-name="leave-alone"></el-table-column>
  <el-table-column label="Name" prop="name"></el-table-column>
  <el-table-column label="Age" prop="age"></el-table-column>
</el-table>

Notes

  • For columns that don't need to be fitted, add a leave-alone class by setting class-name in <el-table-column>.

使用情况

  1. 存在闪动问题

定时器导致

import "./styles.css";

function adjustColumnWidth(table, padding = 32) {
  const colgroup = table.querySelector("colgroup");
  const colDefs = [...colgroup.querySelectorAll("col")];
  colDefs.forEach((col) => {
    const clsName = col.getAttribute("name");
    const cells = [
      ...table.querySelectorAll(`td.${clsName}`),
      ...table.querySelectorAll(`th.${clsName}`),
    ];
    if (cells[0]?.classList?.contains?.("leave-alone")) {
      return;
    }
    const widthList = cells.map((el) => {
      return el.querySelector(".cell")?.scrollWidth || 0;
    });
    const max = Math.max(...widthList);
    table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => {
      el.setAttribute("width", max + padding);
    });
  });
}

export default {
  install(Vue) {
    Vue.directive("fit-columns", {
      update() {},
      bind() {},
      inserted(el, binding) {
        setTimeout(() => {
          adjustColumnWidth(el, binding.value);
        }, 300);
      },
      componentUpdated(el, binding) {
        el.classList.add("r-table");
        setTimeout(() => {
          adjustColumnWidth(el, binding.value);
        }, 300);
      },
      unbind() {},
    });
  },
};

  1. 存在固定行时,存在计算错误,滚动条无法滚动问题

我的方法

计算设置行宽

<el-table-column :width="calcWidth(col)"></el-table-column>
methods: {
    calcWidth(col) {
      const options = {
        handle: (() => {
          return this.calcHandleWidth();
        })(),
      };
      return options[col.titleCode] || col.titleWidth;
    },
    calcDynamicWidth(fontNum = 0, margin = 0, offset=1.2) {
      return (
        fontNum *
          Number(document.documentElement.style.fontSize.replace('px', '')) * // rem 值兼容
          offset + // 误差
        margin
      );
    },
    /**
     * @method calcHandleWidth
     * @description 计算操作列文字数量和边距
     */
    calcHandleWidth() {
      let fontNum = 0,
        list = this.data
          ?.find(
            (v) =>
              v.operating.length ===
              Math.max(...this.data.map((v) => v.operating.length))
          )
          ?.operating?.filter((v) => v.systemShow == 1);
      list
        ? (() => {
            for (let v of list) {
              fontNum += v.operationName.length;
            }
          })()
        : '';
      return this.calcDynamicWidth(fontNum, 20 + (list?.length - 1) * 10);  // 20 左右边距  * 10 按钮之间边距
    },
}
posted @ 2022-02-16 18:13  zc-lee  阅读(3803)  评论(0编辑  收藏  举报