vxe-table 3.12.0-beta.11 → 3.12.0-beta.13

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.
@@ -2,7 +2,6 @@ import XEUtils from 'xe-utils';
2
2
  import { VxeUI } from '../../../ui';
3
3
  import { isColumnInfo, mergeBodyMethod, getCellValue } from '../../src/util';
4
4
  import { parseFile, formatText, eqEmptyValue } from '../../../ui/src/utils';
5
- import { browse } from '../../../ui/src/dom';
6
5
  import { createHtmlPage, getExportBlobByContent } from './util';
7
6
  import { warnLog, errLog } from '../../../ui/src/log';
8
7
  const { getI18n, renderer } = VxeUI;
@@ -10,15 +9,8 @@ let htmlCellElem;
10
9
  // 导入
11
10
  let fileForm;
12
11
  let fileInput;
13
- // 打印
14
- let printFrame;
15
12
  const csvBOM = '\ufeff';
16
13
  const enterSymbol = '\r\n';
17
- function createFrame() {
18
- const frame = document.createElement('iframe');
19
- frame.className = 'vxe-table--print-frame';
20
- return frame;
21
- }
22
14
  function hasTreeChildren($xetable, row) {
23
15
  const treeOpts = $xetable.treeOpts;
24
16
  const childrenField = treeOpts.children || treeOpts.childrenField;
@@ -583,24 +575,25 @@ function clearColumnConvert(columns) {
583
575
  delete column.childNodes;
584
576
  }, { children: 'children' });
585
577
  }
586
- function handleExport($xetable, opts) {
578
+ function handleExport($xeTable, opts) {
579
+ const $xeGrid = $xeTable.$xeGrid;
587
580
  const { remote, columns, colgroups, exportMethod, afterExportMethod } = opts;
588
581
  return new Promise(resolve => {
589
582
  if (remote) {
590
- const params = { options: opts, $table: $xetable, $grid: $xetable.$xegrid };
583
+ const params = { options: opts, $table: $xeTable, $grid: $xeGrid };
591
584
  resolve(exportMethod ? exportMethod(params) : params);
592
585
  }
593
586
  else {
594
- const datas = getExportData($xetable, opts);
595
- resolve($xetable.preventEvent(null, 'event.export', { options: opts, columns, colgroups, datas }, () => {
596
- return downloadFile($xetable, opts, getContent($xetable, opts, columns, datas));
587
+ const datas = getExportData($xeTable, opts);
588
+ resolve($xeTable.preventEvent(null, 'event.export', { options: opts, columns, colgroups, datas }, () => {
589
+ return downloadFile($xeTable, opts, getContent($xeTable, opts, columns, datas));
597
590
  }));
598
591
  }
599
592
  }).then((params) => {
600
593
  clearColumnConvert(columns);
601
594
  if (!opts.print) {
602
595
  if (afterExportMethod) {
603
- afterExportMethod({ status: true, options: opts, $table: $xetable, $grid: $xetable.$xegrid });
596
+ afterExportMethod({ status: true, options: opts, $table: $xeTable, $grid: $xeGrid });
604
597
  }
605
598
  }
606
599
  return Object.assign({ status: true }, params);
@@ -608,7 +601,7 @@ function handleExport($xetable, opts) {
608
601
  clearColumnConvert(columns);
609
602
  if (!opts.print) {
610
603
  if (afterExportMethod) {
611
- afterExportMethod({ status: false, options: opts, $table: $xetable, $grid: $xetable.$xegrid });
604
+ afterExportMethod({ status: false, options: opts, $table: $xeTable, $grid: $xeGrid });
612
605
  }
613
606
  }
614
607
  const params = { status: false };
@@ -948,58 +941,11 @@ export function readLocalFile(options = {}) {
948
941
  fileInput.click();
949
942
  });
950
943
  }
951
- function removePrintFrame() {
952
- if (printFrame) {
953
- if (printFrame.parentNode) {
954
- try {
955
- printFrame.contentDocument.write('');
956
- }
957
- catch (e) { }
958
- printFrame.parentNode.removeChild(printFrame);
959
- }
960
- printFrame = null;
961
- }
962
- }
963
- function appendPrintFrame() {
964
- if (!printFrame.parentNode) {
965
- document.body.appendChild(printFrame);
966
- }
967
- }
968
- function afterPrintEvent() {
969
- requestAnimationFrame(removePrintFrame);
970
- }
971
- export function handlePrint($xetable, opts, content) {
972
- const { beforePrintMethod } = opts;
973
- if (beforePrintMethod) {
974
- content = beforePrintMethod({ content, options: opts, $table: $xetable }) || '';
975
- }
976
- content = createHtmlPage(opts, content);
977
- const blob = getExportBlobByContent(content, opts);
978
- if (browse.msie) {
979
- removePrintFrame();
980
- printFrame = createFrame();
981
- appendPrintFrame();
982
- printFrame.contentDocument.write(content);
983
- printFrame.contentDocument.execCommand('print');
984
- }
985
- else {
986
- if (!printFrame) {
987
- printFrame = createFrame();
988
- printFrame.onload = (evnt) => {
989
- if (evnt.target.src) {
990
- evnt.target.contentWindow.onafterprint = afterPrintEvent;
991
- evnt.target.contentWindow.print();
992
- }
993
- };
994
- }
995
- appendPrintFrame();
996
- printFrame.src = URL.createObjectURL(blob);
997
- }
998
- }
999
- function handleExportAndPrint($xetable, options, isPrint) {
1000
- const { $xegrid, initStore, customOpts, collectColumn, footerTableData, treeConfig, mergeList, isGroup, exportParams, exportOpts } = $xetable;
1001
- const proxyOpts = $xegrid ? $xegrid.proxyOpts : {};
1002
- const selectRecords = $xetable.getCheckboxRecords();
944
+ function handleExportAndPrint($xeTable, options, isPrint) {
945
+ const $xeGrid = $xeTable.$xeGrid;
946
+ const { initStore, customOpts, collectColumn, footerTableData, treeConfig, mergeList, isGroup, exportParams, exportOpts } = $xeTable;
947
+ const proxyOpts = $xeGrid ? $xeGrid.computeProxyOpts : {};
948
+ const selectRecords = $xeTable.getCheckboxRecords();
1003
949
  const hasFooter = !!footerTableData.length;
1004
950
  const hasTree = treeConfig;
1005
951
  const hasMerge = !hasTree && mergeList.length;
@@ -1070,7 +1016,7 @@ function handleExportAndPrint($xetable, options, isPrint) {
1070
1016
  }
1071
1017
  });
1072
1018
  // 更新条件
1073
- Object.assign($xetable.exportStore, {
1019
+ Object.assign($xeTable.exportStore, {
1074
1020
  columns: exportColumns,
1075
1021
  typeList,
1076
1022
  modeList,
@@ -1085,14 +1031,39 @@ function handleExportAndPrint($xetable, options, isPrint) {
1085
1031
  Object.assign(exportParams, {
1086
1032
  mode: selectRecords.length ? 'selected' : 'current'
1087
1033
  }, defOpts);
1088
- if (!modeList.some((item) => item.value === exportParams.mode)) {
1034
+ const { filename, sheetName, mode, type } = exportParams;
1035
+ if (filename) {
1036
+ if (XEUtils.isFunction(filename)) {
1037
+ exportParams.filename = filename({
1038
+ options: defOpts,
1039
+ $table: $xeTable,
1040
+ $grid: $xeGrid
1041
+ });
1042
+ }
1043
+ else {
1044
+ exportParams.filename = `${filename}`;
1045
+ }
1046
+ }
1047
+ if (sheetName) {
1048
+ if (XEUtils.isFunction(sheetName)) {
1049
+ exportParams.sheetName = sheetName({
1050
+ options: defOpts,
1051
+ $table: $xeTable,
1052
+ $grid: $xeGrid
1053
+ });
1054
+ }
1055
+ else {
1056
+ exportParams.sheetName = `${sheetName}`;
1057
+ }
1058
+ }
1059
+ if (!modeList.some(item => item.value === mode)) {
1089
1060
  exportParams.mode = modeList[0].value;
1090
1061
  }
1091
- if (!typeList.some((item) => item.value === exportParams.type)) {
1062
+ if (!typeList.some(item => item.value === type)) {
1092
1063
  exportParams.type = typeList[0].value;
1093
1064
  }
1094
1065
  initStore.export = true;
1095
- return $xetable.$nextTick();
1066
+ return $xeTable.$nextTick();
1096
1067
  }
1097
1068
  const getConvertColumns = (columns) => {
1098
1069
  const result = [];
@@ -1153,11 +1124,13 @@ export default {
1153
1124
  /**
1154
1125
  * 导出文件,支持 csv/html/xml/txt
1155
1126
  * 如果是树表格,则默认是导出所有节点
1156
- * 如果是启用了虚拟滚动,则只能导出数据源,可以配合 dataFilterMethod 函数自行转换数据
1127
+ * 如果是启用了虚拟滚动,则只能导出数据源,可以配合 dataFilterMethod 函数转换数据
1157
1128
  * @param {Object} options 参数
1158
1129
  */
1159
1130
  _exportData(options) {
1160
- const { $xegrid, isGroup, tableGroupColumn, tableFullColumn, afterFullData, treeConfig, treeOpts, exportOpts } = this;
1131
+ const $xeTable = this;
1132
+ const $xeGrid = $xeTable.$xeGrid;
1133
+ const { isGroup, tableGroupColumn, tableFullColumn, afterFullData, treeConfig, treeOpts, exportOpts } = this;
1161
1134
  const opts = Object.assign({
1162
1135
  // filename: '',
1163
1136
  // sheetName: '',
@@ -1182,13 +1155,13 @@ export default {
1182
1155
  }, exportOpts, {
1183
1156
  print: false
1184
1157
  }, options);
1185
- const { type, mode, columns, original, beforeExportMethod, excludeFields, includeFields } = opts;
1158
+ const { filename, sheetName, type, mode, columns, original, columnFilterMethod, beforeExportMethod, includeFields, excludeFields } = opts;
1186
1159
  let groups = [];
1187
1160
  const customCols = columns && columns.length ? columns : null;
1161
+ const handleOptions = Object.assign({}, opts, { filename: '', sheetName: '', colgroups: [], columns: [], data: [] });
1188
1162
  // 如果设置源数据,则默认导出设置了字段的列
1189
- let columnFilterMethod = opts.columnFilterMethod;
1190
1163
  if (!customCols && !columnFilterMethod) {
1191
- columnFilterMethod = ({ column }) => {
1164
+ handleOptions.columnFilterMethod = ({ column }) => {
1192
1165
  if (excludeFields) {
1193
1166
  if (XEUtils.includes(excludeFields, column.field)) {
1194
1167
  return false;
@@ -1204,28 +1177,28 @@ export default {
1204
1177
  };
1205
1178
  }
1206
1179
  if (customCols) {
1207
- opts._isCustomColumn = true;
1208
- groups = XEUtils.searchTree(XEUtils.mapTree(customCols, item => {
1180
+ handleOptions._isCustomColumn = true;
1181
+ groups = XEUtils.searchTree(XEUtils.mapTree(customCols, (item) => {
1209
1182
  let targetColumn;
1210
1183
  if (item) {
1211
1184
  if (isColumnInfo(item)) {
1212
1185
  targetColumn = item;
1213
1186
  }
1214
1187
  else if (XEUtils.isString(item)) {
1215
- targetColumn = this.getColumnByField(item);
1188
+ targetColumn = $xeTable.getColumnByField(item);
1216
1189
  }
1217
1190
  else {
1218
1191
  const colid = item.id || item.colId;
1219
1192
  const type = item.type;
1220
1193
  const field = item.field;
1221
1194
  if (colid) {
1222
- targetColumn = this.getColumnById(colid);
1195
+ targetColumn = $xeTable.getColumnById(colid);
1223
1196
  }
1224
1197
  else if (field && type) {
1225
1198
  targetColumn = tableFullColumn.find((column) => column.field === field && column.type === type);
1226
1199
  }
1227
1200
  else if (field) {
1228
- targetColumn = this.getColumnByField(field);
1201
+ targetColumn = $xeTable.getColumnByField(field);
1229
1202
  }
1230
1203
  else if (type) {
1231
1204
  targetColumn = tableFullColumn.find((column) => column.type === type);
@@ -1236,7 +1209,7 @@ export default {
1236
1209
  }, {
1237
1210
  children: 'childNodes',
1238
1211
  mapChildren: '_children'
1239
- }), (column, index) => isColumnInfo(column) && (!columnFilterMethod || columnFilterMethod({ column, $columnIndex: index })), {
1212
+ }), (column, index) => isColumnInfo(column) && (!columnFilterMethod || columnFilterMethod({ column: column, $columnIndex: index })), {
1240
1213
  children: '_children',
1241
1214
  mapChildren: 'childNodes',
1242
1215
  original: true
@@ -1254,16 +1227,40 @@ export default {
1254
1227
  }
1255
1228
  }, { children: 'childNodes' });
1256
1229
  // 构建分组层级
1257
- opts.columns = cols;
1258
- opts.colgroups = convertToRows(groups);
1259
- if (!opts.filename) {
1260
- opts.filename = getI18n(opts.original ? 'vxe.table.expOriginFilename' : 'vxe.table.expFilename', [XEUtils.toDateString(Date.now(), 'yyyyMMddHHmmss')]);
1230
+ handleOptions.columns = cols;
1231
+ handleOptions.colgroups = convertToRows(groups);
1232
+ if (filename) {
1233
+ if (XEUtils.isFunction(filename)) {
1234
+ handleOptions.filename = filename({
1235
+ options: opts,
1236
+ $table: $xeTable,
1237
+ $grid: $xeGrid
1238
+ });
1239
+ }
1240
+ else {
1241
+ handleOptions.filename = `${filename}`;
1242
+ }
1243
+ }
1244
+ if (!handleOptions.filename) {
1245
+ handleOptions.filename = getI18n(handleOptions.original ? 'vxe.table.expOriginFilename' : 'vxe.table.expFilename', [XEUtils.toDateString(Date.now(), 'yyyyMMddHHmmss')]);
1261
1246
  }
1262
- if (!opts.sheetName) {
1263
- opts.sheetName = document.title;
1247
+ if (sheetName) {
1248
+ if (XEUtils.isFunction(sheetName)) {
1249
+ handleOptions.sheetName = sheetName({
1250
+ options: opts,
1251
+ $table: $xeTable,
1252
+ $grid: $xeGrid
1253
+ });
1254
+ }
1255
+ else {
1256
+ handleOptions.sheetName = `${sheetName}`;
1257
+ }
1258
+ }
1259
+ if (!handleOptions.sheetName) {
1260
+ handleOptions.sheetName = document.title || '';
1264
1261
  }
1265
1262
  // 检查类型,如果为自定义导出,则不需要校验类型
1266
- if (!opts.exportMethod && !XEUtils.includes(XEUtils.keys(exportOpts._typeMaps), type)) {
1263
+ if (!handleOptions.exportMethod && !XEUtils.includes(XEUtils.keys(exportOpts._typeMaps), type)) {
1267
1264
  errLog('vxe.error.notType', [type]);
1268
1265
  if (process.env.NODE_ENV === 'development') {
1269
1266
  if (['xlsx', 'pdf'].includes(type)) {
@@ -1273,17 +1270,17 @@ export default {
1273
1270
  const params = { status: false };
1274
1271
  return Promise.reject(params);
1275
1272
  }
1276
- if (!opts.print) {
1273
+ if (!handleOptions.print) {
1277
1274
  if (beforeExportMethod) {
1278
- beforeExportMethod({ options: opts, $table: this, $grid: $xegrid });
1275
+ beforeExportMethod({ options: handleOptions, $table: $xeTable, $grid: $xeGrid });
1279
1276
  }
1280
1277
  }
1281
1278
  if (!opts.data) {
1282
- opts.data = [];
1279
+ handleOptions.data = [];
1283
1280
  if (mode === 'selected') {
1284
- const selectRecords = this.getCheckboxRecords();
1281
+ const selectRecords = $xeTable.getCheckboxRecords();
1285
1282
  if (['html', 'pdf'].indexOf(type) > -1 && treeConfig) {
1286
- opts.data = XEUtils.searchTree(this.getTableData().fullData, (item) => selectRecords.indexOf(item) > -1, Object.assign({}, treeOpts, { data: '_row' }));
1283
+ opts.data = XEUtils.searchTree($xeTable.getTableData().fullData, item => $xeTable.findRowIndexOf(selectRecords, item) > -1, Object.assign({}, treeOpts, { data: '_row' }));
1287
1284
  }
1288
1285
  else {
1289
1286
  opts.data = selectRecords;
@@ -1291,12 +1288,16 @@ export default {
1291
1288
  }
1292
1289
  else if (mode === 'all') {
1293
1290
  if (process.env.NODE_ENV === 'development') {
1294
- if (!$xegrid) {
1291
+ if (!$xeGrid) {
1295
1292
  warnLog('vxe.error.errProp', ['all', 'mode=current,selected']);
1296
1293
  }
1297
1294
  }
1298
- if ($xegrid && !opts.remote) {
1299
- const { beforeQueryAll, afterQueryAll, ajax = {}, props = {} } = $xegrid.proxyOpts;
1295
+ if ($xeGrid && !handleOptions.remote) {
1296
+ const gridReactData = $xeGrid;
1297
+ const proxyOpts = $xeGrid.computeProxyOpts;
1298
+ const { sortData } = gridReactData;
1299
+ const { beforeQueryAll, afterQueryAll, ajax = {} } = proxyOpts;
1300
+ const resConfigs = proxyOpts.response || proxyOpts.props || {};
1300
1301
  const ajaxMethods = ajax.queryAll;
1301
1302
  const queryAllSuccessMethods = ajax.queryAllSuccess;
1302
1303
  const queryAllErrorMethods = ajax.queryAllError;
@@ -1307,24 +1308,25 @@ export default {
1307
1308
  }
1308
1309
  if (ajaxMethods) {
1309
1310
  const params = {
1310
- $table: this,
1311
- $grid: $xegrid,
1312
- sort: $xegrid.sortData,
1313
- filters: $xegrid.filterData,
1314
- form: $xegrid.formData,
1315
- target: ajaxMethods,
1316
- options: opts
1311
+ $table: $xeTable,
1312
+ $grid: $xeGrid,
1313
+ sort: sortData.length ? sortData[0] : {},
1314
+ sorts: sortData,
1315
+ filters: gridReactData.filterData,
1316
+ form: gridReactData.formData,
1317
+ options: handleOptions
1317
1318
  };
1318
1319
  return Promise.resolve((beforeQueryAll || ajaxMethods)(params))
1319
1320
  .then(rest => {
1320
- opts.data = (props.list ? XEUtils.get(rest, props.list) : rest) || [];
1321
+ const listProp = resConfigs.list;
1322
+ handleOptions.data = (listProp ? (XEUtils.isFunction(listProp) ? listProp({ data: rest, $grid: $xeGrid }) : XEUtils.get(rest, listProp)) : rest) || [];
1321
1323
  if (afterQueryAll) {
1322
1324
  afterQueryAll(params);
1323
1325
  }
1324
1326
  if (queryAllSuccessMethods) {
1325
1327
  queryAllSuccessMethods(Object.assign(Object.assign({}, params), { response: rest }));
1326
1328
  }
1327
- return handleExport(this, opts);
1329
+ return handleExport($xeTable, handleOptions);
1328
1330
  })
1329
1331
  .catch((rest) => {
1330
1332
  if (queryAllErrorMethods) {
@@ -1335,10 +1337,10 @@ export default {
1335
1337
  }
1336
1338
  }
1337
1339
  else if (mode === 'current') {
1338
- opts.data = afterFullData;
1340
+ handleOptions.data = afterFullData;
1339
1341
  }
1340
1342
  }
1341
- return handleExport(this, opts);
1343
+ return handleExport($xeTable, opts);
1342
1344
  },
1343
1345
  _importByFile(file, options) {
1344
1346
  const opts = Object.assign({}, options);
@@ -1376,6 +1378,8 @@ export default {
1376
1378
  return readLocalFile(options);
1377
1379
  },
1378
1380
  _print(options) {
1381
+ const $xeTable = this;
1382
+ const $xeGrid = $xeTable.$xeGrid;
1379
1383
  const opts = Object.assign({
1380
1384
  original: false
1381
1385
  // beforePrintMethod
@@ -1385,22 +1389,73 @@ export default {
1385
1389
  remote: false,
1386
1390
  print: true
1387
1391
  });
1388
- if (!opts.sheetName) {
1389
- opts.sheetName = document.title;
1392
+ const { sheetName } = opts;
1393
+ let printTitle = '';
1394
+ if (sheetName) {
1395
+ if (XEUtils.isFunction(sheetName)) {
1396
+ printTitle = sheetName({
1397
+ options: opts,
1398
+ $table: $xeTable,
1399
+ $grid: $xeGrid
1400
+ });
1401
+ }
1402
+ else {
1403
+ printTitle = `${sheetName}`;
1404
+ }
1390
1405
  }
1391
- return new Promise(resolve => {
1392
- if (opts.content) {
1393
- resolve(handlePrint(this, opts, opts.content));
1406
+ if (!printTitle) {
1407
+ printTitle = document.title || '';
1408
+ }
1409
+ const beforePrintMethod = opts.beforePrintMethod;
1410
+ const tableHtml = opts.html || opts.content;
1411
+ return new Promise((resolve, reject) => {
1412
+ if (VxeUI.print) {
1413
+ if (tableHtml) {
1414
+ resolve(VxeUI.print({
1415
+ title: printTitle,
1416
+ html: tableHtml,
1417
+ customStyle: opts.style,
1418
+ beforeMethod: beforePrintMethod
1419
+ ? ({ html }) => {
1420
+ return beforePrintMethod({
1421
+ html,
1422
+ content: html,
1423
+ options: opts,
1424
+ $table: $xeTable
1425
+ });
1426
+ }
1427
+ : undefined
1428
+ }));
1429
+ }
1430
+ else {
1431
+ resolve($xeTable.exportData(opts).then(({ content }) => {
1432
+ return VxeUI.print({
1433
+ title: printTitle,
1434
+ html: content,
1435
+ customStyle: opts.style,
1436
+ beforeMethod: beforePrintMethod
1437
+ ? ({ html }) => {
1438
+ return beforePrintMethod({
1439
+ html,
1440
+ content: html,
1441
+ options: opts,
1442
+ $table: $xeTable
1443
+ });
1444
+ }
1445
+ : undefined
1446
+ });
1447
+ }));
1448
+ }
1394
1449
  }
1395
1450
  else {
1396
- resolve(this.exportData(opts).then(({ content }) => {
1397
- return handlePrint(this, opts, content);
1398
- }));
1451
+ const e = { status: false };
1452
+ reject(e);
1399
1453
  }
1400
1454
  });
1401
1455
  },
1402
1456
  _getPrintHtml(options) {
1403
- const { printOpts } = this;
1457
+ const $xeTable = this;
1458
+ const printOpts = $xeTable.computePrintOpts;
1404
1459
  const opts = Object.assign({
1405
1460
  original: false
1406
1461
  // beforePrintMethod
@@ -1410,7 +1465,7 @@ export default {
1410
1465
  remote: false,
1411
1466
  print: true
1412
1467
  });
1413
- return this.exportData(opts).then(({ content }) => {
1468
+ return $xeTable.exportData(opts).then(({ content }) => {
1414
1469
  return {
1415
1470
  html: content
1416
1471
  };
@@ -346,17 +346,23 @@ export default defineVxeComponent({
346
346
  /**
347
347
  * 渲染按钮
348
348
  */
349
- renderBtns(h) {
349
+ renderLeftBtns(h) {
350
350
  // 使用已安装的组件,如果未安装则不渲染
351
351
  const VxeUIButtonComponent = VxeUI.getComponent('VxeButton');
352
352
  const $xeToolbar = this;
353
353
  const props = $xeToolbar;
354
+ const slots = $xeToolbar.$scopedSlots;
354
355
  const internalData = $xeToolbar.internalData;
355
356
  const $xeGrid = $xeToolbar.$xeGrid;
356
357
  const { buttons } = props;
357
358
  const { connectTable } = internalData;
358
359
  const $table = connectTable;
360
+ const buttonPrefixSlot = slots.buttonPrefix || slots['button-prefix'];
361
+ const buttonSuffixSlot = slots.buttonSuffix || slots['button-suffix'];
359
362
  const btnVNs = [];
363
+ if (buttonPrefixSlot) {
364
+ btnVNs.push(...getSlotVNs(buttonPrefixSlot.call($xeToolbar, { buttons: buttons || [], $grid: $xeGrid, $table: $table })));
365
+ }
360
366
  if (buttons) {
361
367
  buttons.forEach((item) => {
362
368
  const { dropdowns, buttonRender } = item;
@@ -405,6 +411,9 @@ export default defineVxeComponent({
405
411
  }
406
412
  });
407
413
  }
414
+ if (buttonSuffixSlot) {
415
+ btnVNs.push(...getSlotVNs(buttonSuffixSlot.call($xeToolbar, { buttons: buttons || [], $grid: $xeGrid, $table: $table })));
416
+ }
408
417
  return btnVNs;
409
418
  },
410
419
  /**
@@ -415,12 +424,18 @@ export default defineVxeComponent({
415
424
  const VxeUIButtonComponent = VxeUI.getComponent('VxeButton');
416
425
  const $xeToolbar = this;
417
426
  const props = $xeToolbar;
427
+ const slots = $xeToolbar.$scopedSlots;
418
428
  const internalData = $xeToolbar.internalData;
419
429
  const $xeGrid = $xeToolbar.$xeGrid;
420
430
  const { tools } = props;
421
431
  const { connectTable } = internalData;
422
432
  const $table = connectTable;
433
+ const toolPrefixSlot = slots.toolPrefix || slots['tool-prefix'];
434
+ const toolSuffixSlot = slots.toolSuffix || slots['tool-suffix'];
423
435
  const btnVNs = [];
436
+ if (toolPrefixSlot) {
437
+ btnVNs.push(...getSlotVNs(toolPrefixSlot.call($xeToolbar, { tools: tools || [], $grid: $xeGrid, $table: $table })));
438
+ }
424
439
  if (tools) {
425
440
  tools.forEach((item, tIndex) => {
426
441
  const { dropdowns, toolRender } = item;
@@ -472,6 +487,9 @@ export default defineVxeComponent({
472
487
  }
473
488
  });
474
489
  }
490
+ if (toolSuffixSlot) {
491
+ btnVNs.push(...getSlotVNs(toolSuffixSlot.call($xeToolbar, { tools: tools || [], $grid: $xeGrid, $table: $table })));
492
+ }
475
493
  return btnVNs;
476
494
  },
477
495
  renderToolImport(h) {
@@ -625,7 +643,7 @@ export default defineVxeComponent({
625
643
  }, [
626
644
  h('div', {
627
645
  class: 'vxe-buttons--wrapper'
628
- }, buttonsSlot ? buttonsSlot({ $grid: $xeGrid, $table: $table }) : $xeToolbar.renderBtns(h)),
646
+ }, buttonsSlot ? buttonsSlot({ $grid: $xeGrid, $table: $table }) : $xeToolbar.renderLeftBtns(h)),
629
647
  h('div', {
630
648
  class: 'vxe-tools--wrapper'
631
649
  }, toolsSlot ? toolsSlot({ $grid: $xeGrid, $table: $table }) : $xeToolbar.renderRightTools(h)),
package/es/ui/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { VxeUI } from '@vxe-ui/core';
2
2
  import { getFuncText } from './src/utils';
3
- export const version = "3.12.0-beta.11";
3
+ export const version = "3.12.0-beta.13";
4
4
  VxeUI.version = version;
5
5
  VxeUI.tableVersion = version;
6
6
  VxeUI.setConfig({
package/es/ui/src/log.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { VxeUI } from '@vxe-ui/core';
2
2
  const { log } = VxeUI;
3
- const version = `table v${"3.12.0-beta.11"}`;
3
+ const version = `table v${"3.12.0-beta.13"}`;
4
4
  export const warnLog = log.create('warn', version);
5
5
  export const errLog = log.create('error', version);
package/es/ui/src/vn.js CHANGED
@@ -26,6 +26,9 @@ export function getChangeEvent(renderOpts) {
26
26
  return 'change';
27
27
  }
28
28
  export function getSlotVNs(vns) {
29
+ if (vns === null || vns === undefined) {
30
+ return [];
31
+ }
29
32
  if (XEUtils.isArray(vns)) {
30
33
  return vns;
31
34
  }