在使用vxetable进行表格二次封装时可能会遇到列冻结需求,对于普通表格只有一层表头而言冻结列是比较容易设置的,
左N列冻结:对表头数组前N个数据设置fixed:left,。
右N列冻结:对表头数组后N个数据设置fixed:right。
但是当需求场景的表格是多级表格的情况下,就需要我们把表头数组的原始数据转换成森林结构。此时就需要对上面的逻辑进行略微修改一下了。
左N列冻结:对表头数组森林结构前N个叶子节点设置fixed:left.
右N列冻结:对表头数组森林结构后N个叶子节点设置fixed:right.
此时想要在多级表头场景下实现冻结列配置化需要以下三个步骤:
- 获取表头数组森林结构中所有叶子节点的数量,leftCount。
- 根据设置的左冻结列数目及右冻结列数目和第一步获取的总叶子节点数目,计算中间未被冻结的列数 unFreezeCol。unFreezeCol = leftCount - leftFreezeCol - rightFreezeCol;
- 根据前两步获取的三个参数,编写递归冻结列的方法。
假设表头数据此时已经从普通数组结构转换成数组森林结构了。
// index.vue
// 在watch 中监听表头数据的变化,进行冻结列的设置
// 先获取表头数据中的叶子结点的总数
const leftCount = getLeafCount(tableNormalOptions.value);
// 获取需要冻结的左列个数
const leftFreezeCol = newVal[1]?.freezeLeftCol;
// 获取需要冻结的右列个数
const rightFreezeCol = newVal[1]?.freezeRightCol;
// 获取未被冻结的列的个数
const unFreezeCol = leftCount - leftFreezeCol - rightFreezeCol;
// 对森林表头设置固定叶子结点列
freezeLeaf(tableNormalOptions.value, 0, leftFreezeCol, unFreezeCol);
/**
* @description: 获取森林数据结构中叶子结点的数目
* @param {any[]} data 森林数据结构
* @return {number} count 森林中叶子结点的数目
*/
const getLeafCount = (data: any):number => {
let count = 0;
if (!Array.isArray(data)) {
return count;
}
data.forEach((item) => {
if (item.child && item.child.length) {
count += getLeafCount(item.child);
} else {
count++;
}
});
return count;
};
/**
* @description: 冻结森林中前n个叶子结点和后m个叶子结点,m=总叶子结点-n-center
* @param {*} data 森林数据结构
* @param {number} index 当前叶子结点索引默认从第0个开始
* @param {number} n 需要冻结的前n个叶子结点数目
* @param {number} center 初始未被冻结的叶子结点数目
* @return {any[]} 返回一个森林表头结构
*/
const freezeLeaf = (data: any, index: number, n: number, center: number) => {
if (!Array.isArray(data)) {
return data;
}
data.forEach((item) => {
if (item.child && item.child.length) {
const { newIndex, newNum, newCenter } = freezeLeaf(item.child, index, n, center);
// eslint-disable-next-line no-param-reassign
index = newIndex;
// eslint-disable-next-line no-param-reassign
n = newNum;
// eslint-disable-next-line no-param-reassign
center = newCenter;
} else {
// eslint-disable-next-line no-param-reassign
if (n > 0) {
// eslint-disable-next-line no-param-reassign
item.fixed = 'left';
// eslint-disable-next-line no-param-reassign
n--;
// eslint-disable-next-line no-param-reassign
center++;
} else if (index >= center) {
// eslint-disable-next-line no-param-reassign
item.fixed = 'right';
}
// eslint-disable-next-line no-param-reassign
index++;
}
});
return {
newIndex: index,
newNum: n,
newCenter: center,
};
};
以上就是对Vxetable 二次封装表格的时候,如何开发配置化冻结列的核心代码及思想,可能还有尚未考虑到的地方。欢迎大家指正。