目录
- 1,效果图
- 2,实现思路
- 3,实现方式
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;
}