@jetlinks-web/components 3.1.15 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/EditTable/CellRender.js +69 -3
- package/es/EditTable/EditTable.js +108 -165
- package/es/EditTable/FormItem.js +234 -95
- package/es/EditTable/consts.js +13 -13
- package/es/EditTable/context.js +3 -2
- package/es/EditTable/fieldPool.js +166 -0
- package/es/EditTable/hooks/index.js +4 -2
- package/es/EditTable/hooks/useValidate.js +121 -51
- package/es/EditTable/hooks/useVirtualTreeTable.js +111 -0
- package/es/EditTable/index.js +0 -4
- package/es/EditTable/style/body.js +15 -2
- package/es/EditTable/style/form.js +2 -2
- package/es/EditTable/style/header.js +2 -2
- package/es/EditTable/style/table.js +2 -1
- package/es/Icon/icon.js +3 -3
- package/es/ProTable/ProTable.js +5 -0
- package/es/Search/Advanced/index.js +1 -1
- package/es/Search/Item.js +13 -1
- package/es/Search/util.js +1 -1
- package/es/VirtualTable/Table.js +367 -0
- package/es/VirtualTable/VirtualBody.js +94 -0
- package/es/VirtualTable/index.js +1 -1
- package/es/VirtualTable/useTreeData.js +243 -0
- package/es/VirtualTable/useVirtualScroll.js +159 -0
- package/lib/EditTable/CellRender.js +69 -3
- package/lib/EditTable/EditTable.js +108 -165
- package/lib/EditTable/FormItem.js +234 -95
- package/lib/EditTable/consts.js +13 -13
- package/lib/EditTable/context.js +3 -2
- package/lib/EditTable/fieldPool.js +173 -0
- package/lib/EditTable/hooks/index.js +15 -2
- package/lib/EditTable/hooks/useValidate.js +120 -50
- package/lib/EditTable/hooks/useVirtualTreeTable.js +117 -0
- package/lib/EditTable/index.js +0 -4
- package/lib/EditTable/style/body.js +15 -2
- package/lib/EditTable/style/form.js +2 -2
- package/lib/EditTable/style/header.js +2 -2
- package/lib/EditTable/style/table.js +2 -1
- package/lib/Icon/icon.js +3 -3
- package/lib/ProTable/ProTable.js +5 -0
- package/lib/Search/Advanced/index.js +1 -1
- package/lib/Search/Item.js +13 -1
- package/lib/Search/util.js +1 -1
- package/lib/VirtualTable/Table.js +374 -0
- package/lib/VirtualTable/VirtualBody.js +100 -0
- package/lib/VirtualTable/index.js +4 -4
- package/lib/VirtualTable/useTreeData.js +250 -0
- package/lib/VirtualTable/useVirtualScroll.js +165 -0
- package/package.json +3 -3
- package/es/EditTable/Body.js +0 -312
- package/es/EditTable/Header.js +0 -164
- package/es/EditTable/HeaderRender.js +0 -12
- package/es/VirtualTable/VirtualTable.js +0 -482
- package/lib/EditTable/Body.js +0 -312
- package/lib/EditTable/Header.js +0 -164
- package/lib/EditTable/HeaderRender.js +0 -12
- package/lib/VirtualTable/VirtualTable.js +0 -482
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
|
+
import { defineComponent, computed, ref, watch, onMounted, onBeforeUnmount, nextTick, toRef, defineExpose, createVNode as _createVNode } from 'vue';
|
|
4
|
+
import { Table } from 'ant-design-vue';
|
|
5
|
+
import { tableProps } from "ant-design-vue/es/table";
|
|
6
|
+
import { useVirtualScroll } from './useVirtualScroll';
|
|
7
|
+
import { useTreeData } from './useTreeData';
|
|
8
|
+
// 展开图标组件
|
|
9
|
+
var ExpandIcon = defineComponent({
|
|
10
|
+
name: 'VirtualExpandIcon',
|
|
11
|
+
props: {
|
|
12
|
+
expanded: Boolean,
|
|
13
|
+
hasChildren: Boolean,
|
|
14
|
+
onExpand: Function,
|
|
15
|
+
prefixCls: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: 'ant-table'
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
setup: function setup(props) {
|
|
21
|
+
var handleClick = function handleClick(e) {
|
|
22
|
+
var _props$onExpand;
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
(_props$onExpand = props.onExpand) === null || _props$onExpand === void 0 ? void 0 : _props$onExpand.call(props);
|
|
25
|
+
};
|
|
26
|
+
return function () {
|
|
27
|
+
if (!props.hasChildren) {
|
|
28
|
+
// 占位符,保持对齐
|
|
29
|
+
return _createVNode("span", {
|
|
30
|
+
"class": "".concat(props.prefixCls, "-row-expand-icon ").concat(props.prefixCls, "-row-expand-icon-spaced")
|
|
31
|
+
}, null);
|
|
32
|
+
}
|
|
33
|
+
return _createVNode("button", {
|
|
34
|
+
"type": "button",
|
|
35
|
+
"class": ["".concat(props.prefixCls, "-row-expand-icon"), props.expanded ? "".concat(props.prefixCls, "-row-expand-icon-expanded") : "".concat(props.prefixCls, "-row-expand-icon-collapsed")],
|
|
36
|
+
"onClick": handleClick,
|
|
37
|
+
"aria-expanded": props.expanded
|
|
38
|
+
}, null);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* 虚拟滚动 Table 组件
|
|
44
|
+
* 完全兼容 a-table 的所有功能,同时支持大数据虚拟滚动
|
|
45
|
+
* 支持树形数据的虚拟滚动
|
|
46
|
+
*/
|
|
47
|
+
export default defineComponent({
|
|
48
|
+
name: 'JVirtualTable',
|
|
49
|
+
inheritAttrs: false,
|
|
50
|
+
props: _objectSpread(_objectSpread({}, tableProps()), {}, {
|
|
51
|
+
virtual: {
|
|
52
|
+
type: [Boolean, Object],
|
|
53
|
+
default: false
|
|
54
|
+
}
|
|
55
|
+
}),
|
|
56
|
+
emits: ['expandedRowsChange', 'expand'],
|
|
57
|
+
setup: function setup(props, _ref) {
|
|
58
|
+
var _virtualConfig$value, _virtualConfig$value2, _virtualConfig$value3;
|
|
59
|
+
var attrs = _ref.attrs,
|
|
60
|
+
slots = _ref.slots,
|
|
61
|
+
expose = _ref.expose,
|
|
62
|
+
emit = _ref.emit;
|
|
63
|
+
// Table ref
|
|
64
|
+
var tableRef = ref();
|
|
65
|
+
var scrollContainerRef = ref();
|
|
66
|
+
// 解析虚拟滚动配置
|
|
67
|
+
var virtualConfig = computed(function () {
|
|
68
|
+
if (!props.virtual) return null;
|
|
69
|
+
if (typeof props.virtual === 'boolean') {
|
|
70
|
+
return props.virtual ? {
|
|
71
|
+
itemHeight: 54,
|
|
72
|
+
overscan: 5,
|
|
73
|
+
threshold: 100
|
|
74
|
+
} : null;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
itemHeight: props.virtual.itemHeight || 54,
|
|
78
|
+
overscan: props.virtual.overscan || 5,
|
|
79
|
+
threshold: props.virtual.threshold || 100
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
// 获取容器高度
|
|
83
|
+
var containerHeight = computed(function () {
|
|
84
|
+
var _props$scroll;
|
|
85
|
+
if (!((_props$scroll = props.scroll) !== null && _props$scroll !== void 0 && _props$scroll.y)) return 0;
|
|
86
|
+
var y = props.scroll.y;
|
|
87
|
+
if (typeof y === 'number') return y;
|
|
88
|
+
// 解析 '500px' 这样的字符串
|
|
89
|
+
var num = parseInt(String(y), 10);
|
|
90
|
+
return isNaN(num) ? 0 : num;
|
|
91
|
+
});
|
|
92
|
+
// 获取子节点字段名
|
|
93
|
+
var childrenColumnName = computed(function () {
|
|
94
|
+
return props.childrenColumnName || 'children';
|
|
95
|
+
});
|
|
96
|
+
// 获取 rowKey
|
|
97
|
+
var rowKeyProp = computed(function () {
|
|
98
|
+
return props.rowKey || 'key';
|
|
99
|
+
});
|
|
100
|
+
// 判断是否为树形数据
|
|
101
|
+
var isTreeData = computed(function () {
|
|
102
|
+
var data = props.dataSource || [];
|
|
103
|
+
return data.some(function (item) {
|
|
104
|
+
var children = item[childrenColumnName.value];
|
|
105
|
+
return children && Array.isArray(children) && children.length > 0;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
// 使用树形数据 hook
|
|
109
|
+
var treeDataResult = useTreeData({
|
|
110
|
+
data: toRef(props, 'dataSource'),
|
|
111
|
+
childrenColumnName: childrenColumnName.value,
|
|
112
|
+
rowKey: rowKeyProp.value,
|
|
113
|
+
defaultExpandedRowKeys: props.defaultExpandedRowKeys,
|
|
114
|
+
expandedRowKeys: props.expandedRowKeys ? toRef(props, 'expandedRowKeys') : undefined,
|
|
115
|
+
defaultExpandAllRows: props.defaultExpandAllRows,
|
|
116
|
+
onExpandedRowsChange: function onExpandedRowsChange(keys) {
|
|
117
|
+
emit('expandedRowsChange', keys);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// 处理展开/折叠
|
|
121
|
+
var handleExpand = function handleExpand(node) {
|
|
122
|
+
treeDataResult.toggle(node.key);
|
|
123
|
+
emit('expand', !node.expanded, node.record);
|
|
124
|
+
};
|
|
125
|
+
// 判断是否启用虚拟滚动
|
|
126
|
+
var shouldEnableVirtual = computed(function () {
|
|
127
|
+
var _props$scroll2, _props$dataSource;
|
|
128
|
+
if (!virtualConfig.value) return false;
|
|
129
|
+
if (!((_props$scroll2 = props.scroll) !== null && _props$scroll2 !== void 0 && _props$scroll2.y)) return false;
|
|
130
|
+
// 对于树形数据,使用扁平化后的数据长度
|
|
131
|
+
var dataLength = isTreeData.value ? treeDataResult.flattenedData.value.length : ((_props$dataSource = props.dataSource) === null || _props$dataSource === void 0 ? void 0 : _props$dataSource.length) || 0;
|
|
132
|
+
return dataLength >= virtualConfig.value.threshold;
|
|
133
|
+
});
|
|
134
|
+
// 虚拟滚动的数据数量(树形数据使用扁平化后的长度)
|
|
135
|
+
var itemCount = computed(function () {
|
|
136
|
+
var _props$dataSource2;
|
|
137
|
+
if (isTreeData.value) {
|
|
138
|
+
return treeDataResult.flattenedData.value.length;
|
|
139
|
+
}
|
|
140
|
+
return ((_props$dataSource2 = props.dataSource) === null || _props$dataSource2 === void 0 ? void 0 : _props$dataSource2.length) || 0;
|
|
141
|
+
});
|
|
142
|
+
// 初始化虚拟滚动
|
|
143
|
+
var virtualScroll = useVirtualScroll({
|
|
144
|
+
itemCount: itemCount,
|
|
145
|
+
containerHeight: containerHeight,
|
|
146
|
+
itemHeight: ((_virtualConfig$value = virtualConfig.value) === null || _virtualConfig$value === void 0 ? void 0 : _virtualConfig$value.itemHeight) || 54,
|
|
147
|
+
overscan: ((_virtualConfig$value2 = virtualConfig.value) === null || _virtualConfig$value2 === void 0 ? void 0 : _virtualConfig$value2.overscan) || 5,
|
|
148
|
+
threshold: ((_virtualConfig$value3 = virtualConfig.value) === null || _virtualConfig$value3 === void 0 ? void 0 : _virtualConfig$value3.threshold) || 100
|
|
149
|
+
});
|
|
150
|
+
// 查找并监听滚动容器
|
|
151
|
+
var findScrollContainer = function findScrollContainer() {
|
|
152
|
+
if (!tableRef.value) return null;
|
|
153
|
+
// 查找 .ant-table-body 元素(这是实际的滚动容器)
|
|
154
|
+
var tableElement = tableRef.value.$el || tableRef.value;
|
|
155
|
+
var scrollBody = tableElement.querySelector('.ant-table-body');
|
|
156
|
+
return scrollBody;
|
|
157
|
+
};
|
|
158
|
+
// 设置滚动监听
|
|
159
|
+
var setupScrollListener = function setupScrollListener() {
|
|
160
|
+
nextTick(function () {
|
|
161
|
+
var container = findScrollContainer();
|
|
162
|
+
if (container) {
|
|
163
|
+
scrollContainerRef.value = container;
|
|
164
|
+
container.addEventListener('scroll', virtualScroll.handleScroll);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
// 移除滚动监听
|
|
169
|
+
var removeScrollListener = function removeScrollListener() {
|
|
170
|
+
if (scrollContainerRef.value) {
|
|
171
|
+
scrollContainerRef.value.removeEventListener('scroll', virtualScroll.handleScroll);
|
|
172
|
+
scrollContainerRef.value = undefined;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
// 监听虚拟滚动启用状态变化
|
|
176
|
+
watch(shouldEnableVirtual, function (enabled) {
|
|
177
|
+
if (enabled) {
|
|
178
|
+
setupScrollListener();
|
|
179
|
+
} else {
|
|
180
|
+
removeScrollListener();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// 生命周期
|
|
184
|
+
onMounted(function () {
|
|
185
|
+
if (shouldEnableVirtual.value) {
|
|
186
|
+
setupScrollListener();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
onBeforeUnmount(function () {
|
|
190
|
+
removeScrollListener();
|
|
191
|
+
});
|
|
192
|
+
// 暴露方法
|
|
193
|
+
defineExpose({
|
|
194
|
+
scrollTo: virtualScroll.scrollTo,
|
|
195
|
+
scrollToIndex: virtualScroll.scrollToIndex,
|
|
196
|
+
// 树形数据相关方法
|
|
197
|
+
expand: treeDataResult.expand,
|
|
198
|
+
collapse: treeDataResult.collapse,
|
|
199
|
+
toggle: treeDataResult.toggle,
|
|
200
|
+
expandAll: treeDataResult.expandAll,
|
|
201
|
+
collapseAll: treeDataResult.collapseAll,
|
|
202
|
+
expandTo: treeDataResult.expandTo,
|
|
203
|
+
isExpanded: treeDataResult.isExpanded
|
|
204
|
+
});
|
|
205
|
+
// 渲染函数
|
|
206
|
+
return function () {
|
|
207
|
+
var _props$indentSize;
|
|
208
|
+
// 不使用虚拟滚动的情况
|
|
209
|
+
if (!shouldEnableVirtual.value) {
|
|
210
|
+
return _createVNode(Table, _objectSpread(_objectSpread({
|
|
211
|
+
"ref": tableRef
|
|
212
|
+
}, attrs), props), slots);
|
|
213
|
+
}
|
|
214
|
+
// 使用虚拟滚动
|
|
215
|
+
var startIndex = virtualScroll.startIndex,
|
|
216
|
+
endIndex = virtualScroll.endIndex,
|
|
217
|
+
offsetY = virtualScroll.offsetY,
|
|
218
|
+
totalHeight = virtualScroll.totalHeight;
|
|
219
|
+
// 准备虚拟滚动数据
|
|
220
|
+
var virtualDataSource;
|
|
221
|
+
var needsCustomIndent = false;
|
|
222
|
+
var indentSize = (_props$indentSize = props.indentSize) !== null && _props$indentSize !== void 0 ? _props$indentSize : 15;
|
|
223
|
+
if (isTreeData.value) {
|
|
224
|
+
// 树形数据:使用扁平化后的数据
|
|
225
|
+
var flatData = treeDataResult.flattenedData.value;
|
|
226
|
+
var visibleNodes = flatData.slice(startIndex.value, endIndex.value);
|
|
227
|
+
// 使用 Proxy 代理原始 record,确保修改能同步到原始数据
|
|
228
|
+
virtualDataSource = visibleNodes.map(function (node) {
|
|
229
|
+
return new Proxy(node.record, {
|
|
230
|
+
get: function get(target, prop) {
|
|
231
|
+
if (prop === '__virtual_tree_node__') {
|
|
232
|
+
return node;
|
|
233
|
+
}
|
|
234
|
+
return Reflect.get(target, prop);
|
|
235
|
+
},
|
|
236
|
+
set: function set(target, prop, value) {
|
|
237
|
+
if (prop !== '__virtual_tree_node__') {
|
|
238
|
+
return Reflect.set(target, prop, value);
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
},
|
|
242
|
+
has: function has(target, prop) {
|
|
243
|
+
if (prop === '__virtual_tree_node__') {
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return Reflect.has(target, prop);
|
|
247
|
+
},
|
|
248
|
+
ownKeys: function ownKeys(target) {
|
|
249
|
+
return [].concat(_toConsumableArray(Reflect.ownKeys(target)), ['__virtual_tree_node__']);
|
|
250
|
+
},
|
|
251
|
+
getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, prop) {
|
|
252
|
+
if (prop === '__virtual_tree_node__') {
|
|
253
|
+
return {
|
|
254
|
+
configurable: true,
|
|
255
|
+
enumerable: false,
|
|
256
|
+
value: node
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
needsCustomIndent = true;
|
|
264
|
+
} else {
|
|
265
|
+
// 普通数据:直接切片
|
|
266
|
+
virtualDataSource = (props.dataSource || []).slice(startIndex.value, endIndex.value);
|
|
267
|
+
}
|
|
268
|
+
// 处理列,添加树形展开功能
|
|
269
|
+
var processedColumns = props.columns;
|
|
270
|
+
if (needsCustomIndent && processedColumns && processedColumns.length > 0) {
|
|
271
|
+
// 克隆 columns,修改第一列以添加展开按钮和缩进
|
|
272
|
+
processedColumns = processedColumns.map(function (col, colIndex) {
|
|
273
|
+
if (colIndex === 0) {
|
|
274
|
+
var originalRender = col.customRender;
|
|
275
|
+
return _objectSpread(_objectSpread({}, col), {}, {
|
|
276
|
+
customRender: function customRender(renderProps) {
|
|
277
|
+
var record = renderProps.record,
|
|
278
|
+
text = renderProps.text,
|
|
279
|
+
index = renderProps.index;
|
|
280
|
+
var treeNode = record.__virtual_tree_node__;
|
|
281
|
+
if (!treeNode) {
|
|
282
|
+
// 非树形数据行,使用原始渲染
|
|
283
|
+
if (originalRender) {
|
|
284
|
+
return originalRender(renderProps);
|
|
285
|
+
}
|
|
286
|
+
return text;
|
|
287
|
+
}
|
|
288
|
+
var level = treeNode.level,
|
|
289
|
+
hasChildren = treeNode.hasChildren,
|
|
290
|
+
expanded = treeNode.expanded;
|
|
291
|
+
var indentStyle = {
|
|
292
|
+
paddingLeft: "".concat(level * indentSize, "px"),
|
|
293
|
+
display: 'inline-flex',
|
|
294
|
+
alignItems: 'center'
|
|
295
|
+
};
|
|
296
|
+
var content = originalRender ? originalRender(renderProps) : text;
|
|
297
|
+
return _createVNode("span", {
|
|
298
|
+
"style": indentStyle
|
|
299
|
+
}, [_createVNode(ExpandIcon, {
|
|
300
|
+
"expanded": expanded,
|
|
301
|
+
"hasChildren": hasChildren,
|
|
302
|
+
"onExpand": function onExpand() {
|
|
303
|
+
return handleExpand(treeNode);
|
|
304
|
+
}
|
|
305
|
+
}, null), _createVNode("span", null, [content])]);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return col;
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
// 自定义 body 组件
|
|
313
|
+
var customComponents = _objectSpread(_objectSpread({}, props.components || {}), {}, {
|
|
314
|
+
body: {
|
|
315
|
+
wrapper: function wrapper(bodyProps, _ref2) {
|
|
316
|
+
var _processedColumns, _bodySlots$default, _processedColumns2;
|
|
317
|
+
var bodySlots = _ref2.slots;
|
|
318
|
+
// 计算底部占位高度
|
|
319
|
+
var accumulatedHeight = offsetY.value;
|
|
320
|
+
for (var i = startIndex.value; i < endIndex.value; i++) {
|
|
321
|
+
accumulatedHeight += virtualScroll.getItemHeight(i);
|
|
322
|
+
}
|
|
323
|
+
var bottomHeight = totalHeight.value - accumulatedHeight;
|
|
324
|
+
return _createVNode("tbody", _objectSpread(_objectSpread({}, bodyProps), {}, {
|
|
325
|
+
"class": "ant-table-tbody"
|
|
326
|
+
}), [offsetY.value > 0 && _createVNode("tr", {
|
|
327
|
+
"aria-hidden": "true",
|
|
328
|
+
"style": {
|
|
329
|
+
height: 0
|
|
330
|
+
}
|
|
331
|
+
}, [_createVNode("td", {
|
|
332
|
+
"style": {
|
|
333
|
+
padding: 0,
|
|
334
|
+
border: 0,
|
|
335
|
+
height: "".concat(offsetY.value, "px")
|
|
336
|
+
},
|
|
337
|
+
"colSpan": ((_processedColumns = processedColumns) === null || _processedColumns === void 0 ? void 0 : _processedColumns.length) || 1
|
|
338
|
+
}, null)]), (_bodySlots$default = bodySlots.default) === null || _bodySlots$default === void 0 ? void 0 : _bodySlots$default.call(bodySlots), bottomHeight > 0 && _createVNode("tr", {
|
|
339
|
+
"aria-hidden": "true",
|
|
340
|
+
"style": {
|
|
341
|
+
height: 0
|
|
342
|
+
}
|
|
343
|
+
}, [_createVNode("td", {
|
|
344
|
+
"style": {
|
|
345
|
+
padding: 0,
|
|
346
|
+
border: 0,
|
|
347
|
+
height: "".concat(bottomHeight, "px")
|
|
348
|
+
},
|
|
349
|
+
"colSpan": ((_processedColumns2 = processedColumns) === null || _processedColumns2 === void 0 ? void 0 : _processedColumns2.length) || 1
|
|
350
|
+
}, null)])]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
// 移除树形数据的 children 配置,因为我们自己处理
|
|
355
|
+
var tableProps = _objectSpread(_objectSpread({}, props), {}, {
|
|
356
|
+
dataSource: virtualDataSource,
|
|
357
|
+
columns: processedColumns,
|
|
358
|
+
components: customComponents
|
|
359
|
+
}, isTreeData.value ? {
|
|
360
|
+
childrenColumnName: '__disabled__'
|
|
361
|
+
} : {});
|
|
362
|
+
return _createVNode(Table, _objectSpread(_objectSpread({
|
|
363
|
+
"ref": tableRef
|
|
364
|
+
}, attrs), tableProps), slots);
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { defineComponent, computed, createVNode as _createVNode } from 'vue';
|
|
2
|
+
import { useVirtualScroll } from './useVirtualScroll';
|
|
3
|
+
/**
|
|
4
|
+
* 虚拟滚动 Body 组件
|
|
5
|
+
* 用于替代 Table 的默认 body
|
|
6
|
+
*/
|
|
7
|
+
export default defineComponent({
|
|
8
|
+
name: 'VirtualBody',
|
|
9
|
+
props: {
|
|
10
|
+
data: {
|
|
11
|
+
type: Array,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
scrollY: {
|
|
15
|
+
type: Number,
|
|
16
|
+
required: true
|
|
17
|
+
},
|
|
18
|
+
itemHeight: {
|
|
19
|
+
type: [Number, Function],
|
|
20
|
+
default: 54
|
|
21
|
+
},
|
|
22
|
+
overscan: {
|
|
23
|
+
type: Number,
|
|
24
|
+
default: 5
|
|
25
|
+
},
|
|
26
|
+
threshold: {
|
|
27
|
+
type: Number,
|
|
28
|
+
default: 100
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
setup: function setup(props, _ref) {
|
|
32
|
+
var slots = _ref.slots;
|
|
33
|
+
var itemCount = computed(function () {
|
|
34
|
+
return props.data.length;
|
|
35
|
+
});
|
|
36
|
+
// 初始化虚拟滚动
|
|
37
|
+
var virtualScroll = useVirtualScroll({
|
|
38
|
+
itemCount: itemCount,
|
|
39
|
+
containerHeight: props.scrollY,
|
|
40
|
+
itemHeight: props.itemHeight,
|
|
41
|
+
overscan: props.overscan,
|
|
42
|
+
threshold: props.threshold
|
|
43
|
+
});
|
|
44
|
+
// 判断是否启用虚拟滚动
|
|
45
|
+
var isVirtualEnabled = computed(function () {
|
|
46
|
+
return props.data.length >= (props.threshold || 100);
|
|
47
|
+
});
|
|
48
|
+
return function () {
|
|
49
|
+
var _slots$default2;
|
|
50
|
+
var data = props.data;
|
|
51
|
+
if (!isVirtualEnabled.value) {
|
|
52
|
+
var _slots$default;
|
|
53
|
+
// 数据量小,不使用虚拟滚动,渲染所有行
|
|
54
|
+
return _createVNode("tbody", {
|
|
55
|
+
"class": "ant-table-tbody"
|
|
56
|
+
}, [(_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots)]);
|
|
57
|
+
}
|
|
58
|
+
// 使用虚拟滚动
|
|
59
|
+
var startIndex = virtualScroll.startIndex,
|
|
60
|
+
endIndex = virtualScroll.endIndex,
|
|
61
|
+
offsetY = virtualScroll.offsetY,
|
|
62
|
+
totalHeight = virtualScroll.totalHeight,
|
|
63
|
+
visibleCount = virtualScroll.visibleCount;
|
|
64
|
+
// 计算底部占位高度
|
|
65
|
+
var bottomHeight = totalHeight.value - offsetY.value;
|
|
66
|
+
var accumulatedHeight = offsetY.value;
|
|
67
|
+
for (var i = startIndex.value; i < endIndex.value; i++) {
|
|
68
|
+
accumulatedHeight += virtualScroll.getItemHeight(i);
|
|
69
|
+
}
|
|
70
|
+
var actualBottomHeight = totalHeight.value - accumulatedHeight;
|
|
71
|
+
return _createVNode("tbody", {
|
|
72
|
+
"class": "ant-table-tbody"
|
|
73
|
+
}, [offsetY.value > 0 && _createVNode("tr", {
|
|
74
|
+
"aria-hidden": "true",
|
|
75
|
+
"class": "ant-table-virtual-placeholder"
|
|
76
|
+
}, [_createVNode("td", {
|
|
77
|
+
"style": {
|
|
78
|
+
padding: 0,
|
|
79
|
+
border: 0,
|
|
80
|
+
height: "".concat(offsetY.value, "px")
|
|
81
|
+
}
|
|
82
|
+
}, null)]), (_slots$default2 = slots.default) === null || _slots$default2 === void 0 ? void 0 : _slots$default2.call(slots), actualBottomHeight > 0 && _createVNode("tr", {
|
|
83
|
+
"aria-hidden": "true",
|
|
84
|
+
"class": "ant-table-virtual-placeholder"
|
|
85
|
+
}, [_createVNode("td", {
|
|
86
|
+
"style": {
|
|
87
|
+
padding: 0,
|
|
88
|
+
border: 0,
|
|
89
|
+
height: "".concat(actualBottomHeight, "px")
|
|
90
|
+
}
|
|
91
|
+
}, null)])]);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
});
|
package/es/VirtualTable/index.js
CHANGED