目录
- 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;
}