自定义表格组件:实现表格中有固定列的功能逻辑

目录

    • 1,效果图
    • 2,实现思路
    • 3,实现方式

1,效果图

可以拖动纵向滑块,最左边一列固定住。
以同样的道理,可以在右面固定一列
自定义表格组件:实现表格中有固定列的功能逻辑_第1张图片

2,实现思路

作为一个table组件,要接受父组件中的对table的数据定义以及对每一个列的数据定义。

因此要实现固定列,就要对父组件传来的每一列的数据进行筛选。
主要的步骤:
1, 用fixed来标记每一列的固定状态。
2,对父组件传来的每一列的数据进行筛选
3,将左固定列,右固定列,主列分别保存在数组里面。
4,将左固定列,右固定列,主列分别用 table标签包装起来,就相当于三个table放在一个div盒子里面。并用左固定列,主列,右固定列的顺序排布。
5,为了产生滚动条,在写主列table的时候外层需要用div去包裹起来,给这个div添加样式,让其可以在一定宽度下进行滚动。
6,并根据左固定列或者右固定列的类型去设置不同的样式,让其固定在左右两边。

3,实现方式

render: function (createElement) { 
// 用来设置左边右边列以及主列的数组
 var vm = this,
      mainCols = [],
      leftCols = [],
      rightCols = [],
// 对父组件传过来的的所有列插槽进行过滤,去分别左固定列,右固定列,主列。  
this.$slots.default.forEach((columnSlot) => {
      var opt = columnSlot.componentOptions;

      if (!opt || opt.tag !== "cvn-table-column") return;

      if (opt.propsData.type === "expand") {
        expandCol = columnSlot;
        return;
      }

      if (opt.propsData.fixed === "right") {
        return rightCols.push(columnSlot);
      } else if (opt.propsData.fixed !== undefined) {
        return leftCols.push(columnSlot);
      } else {
        return mainCols.push(columnSlot);
      }
    });
 // 将固定列使用fixed参数进行标记
 leftCols.forEach(
      (col) => (col.componentOptions.propsData["position"] = "fixed")
    );
    rightCols.forEach(
      (col) => (col.componentOptions.propsData["position"] = "fixed")
    );
    mainCols = leftCols.concat(mainCols, rightCols);
}
// 构造table表格的函数代码
 function parseTable(cols, fixed) {
      if (fixed === "right") mark = "right";
      return createElement(
        "table",
        {
          class: {
            "cvn-table-inner": true,
            "cvn-table-simple": vm.theme === "simple",
            "cvn-table-main": fixed === undefined,
            "cvn-table-fixed-left": fixed === "left",
            "cvn-table-fixed-right": fixed === "right",
            "cvn-table-oneline": vm.validOneline,
          },
          attrs: {
            "cvn-table-id": vm.tableID,
            name:
              fixed === "left"
                ? "cvn-table-fixed-left"
                : fixed === "right"
                ? "cvn-table-fixed-right"
                : "cvn-table-main",
          },
        },
        [
          createElement(
            "thead",
            {
              class: {
                "cvn-table-row-container": true,
                "cvn-table-head-row": vm.height,
              },
            },
            [parseHeader(cols)]
          ),
          createElement(
            "tbody",
            {
              class: {
                "cvn-table-row-container": true,
              },
              attrs: {
                name: "cvn-table-body",
              },
              },
            },
            vm.validData.length === 0
              ? [parseEmptyRow(cols.length, fixed === undefined ? true : false)]
              : expandCol
              ? parseRowPairs(
                  cols,
                  fixed === undefined ? expandCol : null,
                  vm.validData
                )
              : vm.validData.map((rowData, index) =>
                  parseRow(cols, rowData, index)
                )
          ),
        ]
      );
    }

使用下面的方法将 整个table表格渲染出来,并给主列外面的div添加了滚动事件。通过leftCols.length的长度来判断是否要构造左固定列所对应的表格。右固定列同理。

function parseMainView() {
      return [
        leftCols.length > 0 ? parseTable(leftCols, "left") : undefined,
        rightCols.length > 0 ? parseTable(rightCols, "right") : undefined,
        createElement(
          "div",
          {
            class: "cvn-table-view",
            on: {
              scroll: () => {
                vm.throttlenScrollWatch && vm.throttlenScrollWatch();
              },
            },
            attrs: {
              name: "cvn-table-view",
            },
          },
          [parseTable(mainCols)]
        ),
      ];
    }

相关css代码:

.cvn-table-new .cvn-table-inner.cvn-table-fixed-left,
.cvn-table-new .cvn-table-inner.cvn-table-fixed-right {
  position: absolute;
  z-index: 1;
}

.cvn-table-new .cvn-table-inner.cvn-table-fixed-left {
  left: 0;
  top: 0;
  transition: box-shadow ease 0.2s;
  border-right: none !important;
}

.cvn-table-new .cvn-table-inner.cvn-table-fixed-right {
  right: 0;
  top: 0;
  transition: box-shadow ease 0.2s;
  border-left: none !important;
}

.cvn-table-new .cvn-table-inner.cvn-table-main .cvn-table-fixed-column {
  visibility: hidden;
}

你可能感兴趣的:(前端,javascript,开发语言)