vxe-table 3.3.16 → 3.4.2

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.
Files changed (45) hide show
  1. package/helper/vetur/attributes.json +12 -200
  2. package/helper/vetur/tags.json +3 -65
  3. package/lib/edit/src/mixin.js +2 -2
  4. package/lib/edit/src/mixin.min.js +1 -1
  5. package/lib/export/src/mixin.js +44 -1
  6. package/lib/export/src/mixin.min.js +1 -1
  7. package/lib/form/src/form.js +21 -6
  8. package/lib/form/src/form.min.js +1 -1
  9. package/lib/form/src/render.js +4 -4
  10. package/lib/form/src/render.min.js +1 -1
  11. package/lib/grid/src/grid.js +56 -0
  12. package/lib/grid/src/grid.min.js +1 -1
  13. package/lib/header/src/header.js +3 -2
  14. package/lib/header/src/header.min.js +1 -1
  15. package/lib/index.umd.js +446 -1065
  16. package/lib/index.umd.min.js +1 -1
  17. package/lib/select/src/select.js +5 -5
  18. package/lib/select/src/select.min.js +1 -1
  19. package/lib/table/src/body.js +15 -10
  20. package/lib/table/src/body.min.js +1 -1
  21. package/lib/table/src/cell.js +92 -35
  22. package/lib/table/src/cell.min.js +1 -1
  23. package/lib/table/src/methods.js +267 -147
  24. package/lib/table/src/methods.min.js +1 -1
  25. package/lib/table/src/table.js +12 -2
  26. package/lib/table/src/table.min.js +1 -1
  27. package/lib/v-x-e-table/src/conf.js +3 -3
  28. package/lib/v-x-e-table/src/conf.min.js +1 -1
  29. package/lib/validator/src/mixin.js +9 -4
  30. package/lib/validator/src/mixin.min.js +1 -1
  31. package/package.json +1 -2
  32. package/packages/edit/src/mixin.js +2 -2
  33. package/packages/export/src/mixin.js +38 -1
  34. package/packages/form/src/form.js +10 -6
  35. package/packages/form/src/render.js +4 -4
  36. package/packages/grid/src/grid.js +48 -0
  37. package/packages/header/src/header.js +2 -2
  38. package/packages/select/src/select.js +5 -5
  39. package/packages/table/src/body.js +15 -10
  40. package/packages/table/src/cell.js +74 -41
  41. package/packages/table/src/methods.js +173 -73
  42. package/packages/table/src/table.js +11 -2
  43. package/packages/v-x-e-table/src/conf.js +3 -3
  44. package/packages/validator/src/mixin.js +8 -4
  45. package/types/table.d.ts +1 -1
@@ -291,17 +291,18 @@ export const Cell = {
291
291
  const { $table, column, isHidden } = params
292
292
  const { radioOpts, selectRow } = $table
293
293
  const { slots } = column
294
- const { labelField, checkMethod } = radioOpts
294
+ const { labelField, checkMethod, visibleMethod } = radioOpts
295
295
  const { row } = params
296
296
  const defaultSlot = slots ? slots.default : null
297
297
  const radioSlot = slots ? slots.radio : null
298
298
  const isChecked = row === selectRow
299
+ const isVisible = !visibleMethod || visibleMethod({ row })
299
300
  let isDisabled = !!checkMethod
300
301
  let on
301
302
  if (!isHidden) {
302
303
  on = {
303
304
  click (evnt) {
304
- if (!isDisabled) {
305
+ if (!isDisabled && isVisible) {
305
306
  $table.triggerRadioRowEvent(evnt, params)
306
307
  }
307
308
  }
@@ -310,26 +311,36 @@ export const Cell = {
310
311
  isDisabled = !checkMethod({ row })
311
312
  }
312
313
  }
313
- const radioParams = { ...params, checked: isChecked, disabled: isDisabled }
314
- return radioSlot ? $table.callSlot(radioSlot, radioParams, h) : [
315
- h('span', {
316
- class: ['vxe-cell--radio', {
317
- 'is--checked': isChecked,
318
- 'is--disabled': isDisabled
319
- }],
320
- on
321
- }, [
314
+ const radioParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible }
315
+ if (radioSlot) {
316
+ return $table.callSlot(radioSlot, radioParams, h)
317
+ }
318
+ const radioVNs = []
319
+ if (isVisible) {
320
+ radioVNs.push(
322
321
  h('span', {
323
322
  class: 'vxe-radio--icon vxe-radio--checked-icon'
324
323
  }),
325
324
  h('span', {
326
325
  class: 'vxe-radio--icon vxe-radio--unchecked-icon'
327
326
  })
328
- ].concat(defaultSlot || labelField ? [
327
+ )
328
+ }
329
+ if (defaultSlot || labelField) {
330
+ radioVNs.push(
329
331
  h('span', {
330
332
  class: 'vxe-radio--label'
331
333
  }, defaultSlot ? $table.callSlot(defaultSlot, radioParams, h) : XEUtils.get(row, labelField))
332
- ] : []))
334
+ )
335
+ }
336
+ return [
337
+ h('span', {
338
+ class: ['vxe-cell--radio', {
339
+ 'is--checked': isChecked,
340
+ 'is--disabled': isDisabled
341
+ }],
342
+ on
343
+ }, radioVNs)
333
344
  ]
334
345
  },
335
346
  renderTreeRadioCell (h, params) {
@@ -401,19 +412,20 @@ export const Cell = {
401
412
  renderSelectionCell (h, params) {
402
413
  const { $table, row, column, isHidden } = params
403
414
  const { treeConfig, treeIndeterminates } = $table
404
- const { labelField, checkMethod } = $table.checkboxOpts
415
+ const { labelField, checkMethod, visibleMethod } = $table.checkboxOpts
405
416
  const { slots } = column
406
417
  const defaultSlot = slots ? slots.default : null
407
418
  const checkboxSlot = slots ? slots.checkbox : null
408
419
  let indeterminate = false
409
420
  let isChecked = false
421
+ const isVisible = !visibleMethod || visibleMethod({ row })
410
422
  let isDisabled = !!checkMethod
411
423
  let on
412
424
  if (!isHidden) {
413
425
  isChecked = $table.selection.indexOf(row) > -1
414
426
  on = {
415
427
  click (evnt) {
416
- if (!isDisabled) {
428
+ if (!isDisabled && isVisible) {
417
429
  $table.triggerCheckRowEvent(evnt, params, !isChecked)
418
430
  }
419
431
  }
@@ -425,16 +437,13 @@ export const Cell = {
425
437
  indeterminate = treeIndeterminates.indexOf(row) > -1
426
438
  }
427
439
  }
428
- const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, indeterminate }
429
- return checkboxSlot ? $table.callSlot(checkboxSlot, checkboxParams, h) : [
430
- h('span', {
431
- class: ['vxe-cell--checkbox', {
432
- 'is--checked': isChecked,
433
- 'is--disabled': isDisabled,
434
- 'is--indeterminate': indeterminate
435
- }],
436
- on
437
- }, [
440
+ const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible, indeterminate }
441
+ if (checkboxSlot) {
442
+ return $table.callSlot(checkboxSlot, checkboxParams, h)
443
+ }
444
+ const checkVNs = []
445
+ if (isVisible) {
446
+ checkVNs.push(
438
447
  h('span', {
439
448
  class: 'vxe-checkbox--icon vxe-checkbox--checked-icon'
440
449
  }),
@@ -444,11 +453,24 @@ export const Cell = {
444
453
  h('span', {
445
454
  class: 'vxe-checkbox--icon vxe-checkbox--indeterminate-icon'
446
455
  })
447
- ].concat(defaultSlot || labelField ? [
456
+ )
457
+ }
458
+ if (defaultSlot || labelField) {
459
+ checkVNs.push(
448
460
  h('span', {
449
461
  class: 'vxe-checkbox--label'
450
462
  }, defaultSlot ? $table.callSlot(defaultSlot, checkboxParams, h) : XEUtils.get(row, labelField))
451
- ] : []))
463
+ )
464
+ }
465
+ return [
466
+ h('span', {
467
+ class: ['vxe-cell--checkbox', {
468
+ 'is--checked': isChecked,
469
+ 'is--disabled': isDisabled,
470
+ 'is--indeterminate': indeterminate
471
+ }],
472
+ on
473
+ }, checkVNs)
452
474
  ]
453
475
  },
454
476
  renderTreeSelectionCell (h, params) {
@@ -457,19 +479,20 @@ export const Cell = {
457
479
  renderSelectionCellByProp (h, params) {
458
480
  const { $table, row, column, isHidden } = params
459
481
  const { treeConfig, treeIndeterminates } = $table
460
- const { labelField, checkField: property, halfField, checkMethod } = $table.checkboxOpts
482
+ const { labelField, checkField: property, halfField, checkMethod, visibleMethod } = $table.checkboxOpts
461
483
  const { slots } = column
462
484
  const defaultSlot = slots ? slots.default : null
463
485
  const checkboxSlot = slots ? slots.checkbox : null
464
486
  let indeterminate = false
465
487
  let isChecked = false
488
+ const isVisible = !visibleMethod || visibleMethod({ row })
466
489
  let isDisabled = !!checkMethod
467
490
  let on
468
491
  if (!isHidden) {
469
492
  isChecked = XEUtils.get(row, property)
470
493
  on = {
471
494
  click (evnt) {
472
- if (!isDisabled) {
495
+ if (!isDisabled && isVisible) {
473
496
  $table.triggerCheckRowEvent(evnt, params, !isChecked)
474
497
  }
475
498
  }
@@ -481,16 +504,13 @@ export const Cell = {
481
504
  indeterminate = treeIndeterminates.indexOf(row) > -1
482
505
  }
483
506
  }
484
- const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, indeterminate }
485
- return checkboxSlot ? $table.callSlot(checkboxSlot, checkboxParams, h) : [
486
- h('span', {
487
- class: ['vxe-cell--checkbox', {
488
- 'is--checked': isChecked,
489
- 'is--disabled': isDisabled,
490
- 'is--indeterminate': halfField && !isChecked ? row[halfField] : indeterminate
491
- }],
492
- on
493
- }, [
507
+ const checkboxParams = { ...params, checked: isChecked, disabled: isDisabled, visible: isVisible, indeterminate }
508
+ if (checkboxSlot) {
509
+ return $table.callSlot(checkboxSlot, checkboxParams, h)
510
+ }
511
+ const checkVNs = []
512
+ if (isVisible) {
513
+ checkVNs.push(
494
514
  h('span', {
495
515
  class: 'vxe-checkbox--icon vxe-checkbox--checked-icon'
496
516
  }),
@@ -500,11 +520,24 @@ export const Cell = {
500
520
  h('span', {
501
521
  class: 'vxe-checkbox--icon vxe-checkbox--indeterminate-icon'
502
522
  })
503
- ].concat(defaultSlot || labelField ? [
523
+ )
524
+ }
525
+ if (defaultSlot || labelField) {
526
+ checkVNs.push(
504
527
  h('span', {
505
528
  class: 'vxe-checkbox--label'
506
529
  }, defaultSlot ? $table.callSlot(defaultSlot, checkboxParams, h) : XEUtils.get(row, labelField))
507
- ] : []))
530
+ )
531
+ }
532
+ return [
533
+ h('span', {
534
+ class: ['vxe-cell--checkbox', {
535
+ 'is--checked': isChecked,
536
+ 'is--disabled': isDisabled,
537
+ 'is--indeterminate': halfField && !isChecked ? row[halfField] : indeterminate
538
+ }],
539
+ on
540
+ }, checkVNs)
508
541
  ]
509
542
  },
510
543
  renderTreeSelectionCellByProp (h, params) {
@@ -306,43 +306,67 @@ const Methods = {
306
306
  this.tableData = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0)
307
307
  return this.$nextTick()
308
308
  },
309
+ updateScrollYStatus (fullData) {
310
+ const { treeConfig, treeOpts, sYOpts } = this
311
+ const { transform } = treeOpts
312
+ const scrollYLoad = (transform || !treeConfig) && !!sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < fullData.length
313
+ this.scrollYLoad = scrollYLoad
314
+ return scrollYLoad
315
+ },
309
316
  /**
310
317
  * 加载表格数据
311
318
  * @param {Array} datas 数据
312
319
  */
313
320
  loadTableData (datas) {
314
- const { keepSource, treeConfig, treeOpts, editStore, sYOpts, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop, scrollYLoad: oldScrollYLoad } = this
315
- if (treeConfig && treeOpts.transform) {
316
- if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
317
- if (!treeOpts.rowtKey) {
318
- UtilTools.error('vxe.error.reqProp', ['table.tree-config.rowtKey'])
319
- }
320
- if (!treeOpts.parentKey) {
321
- UtilTools.error('vxe.error.reqProp', ['table.tree-config.parentKey'])
321
+ const { keepSource, treeConfig, treeOpts, editStore, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop, scrollYLoad: oldScrollYLoad } = this
322
+ let treeData = []
323
+ let fullData = datas ? datas.slice(0) : []
324
+ if (treeConfig) {
325
+ // 树结构自动转换
326
+ if (treeOpts.transform) {
327
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
328
+ if (!treeOpts.rowField) {
329
+ UtilTools.error('vxe.error.reqProp', ['table.tree-config.rowField'])
330
+ }
331
+ if (!treeOpts.parentField) {
332
+ UtilTools.error('vxe.error.reqProp', ['table.tree-config.parentField'])
333
+ }
334
+ if (!treeOpts.children) {
335
+ UtilTools.error('vxe.error.reqProp', ['tree-config.children'])
336
+ }
337
+ fullData.forEach(row => {
338
+ if (row[treeOpts.children] && row[treeOpts.children].length) {
339
+ UtilTools.warn('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
340
+ }
341
+ })
322
342
  }
343
+ treeData = XEUtils.toArrayTree(fullData, { key: treeOpts.rowField, parentKey: treeOpts.parentField, children: treeOpts.children })
344
+ fullData = treeData.slice(0)
345
+ } else {
346
+ treeData = fullData.slice(0)
323
347
  }
324
- datas = XEUtils.toArrayTree(datas, { key: treeOpts.rowtKey, parentKey: treeOpts.parentKey, children: treeOpts.children })
325
348
  }
326
- const tableFullData = datas ? datas.slice(0) : []
327
- const scrollYLoad = !treeConfig && sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < tableFullData.length
328
349
  scrollYStore.startIndex = 0
329
350
  scrollYStore.endIndex = 1
330
351
  scrollXStore.startIndex = 0
331
352
  scrollXStore.endIndex = 1
332
353
  editStore.insertList = []
333
354
  editStore.removeList = []
355
+ const sYLoad = this.updateScrollYStatus(fullData)
356
+ this.scrollYLoad = sYLoad
334
357
  // 全量数据
335
- this.tableFullData = tableFullData
358
+ this.tableFullData = fullData
359
+ this.treeFullData = treeData
336
360
  // 缓存数据
337
- this.updateCache(true)
361
+ this.cacheRowMap(true)
338
362
  // 原始数据
339
363
  this.tableSynchData = datas
364
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
340
365
  if (keepSource) {
341
- this.tableSourceData = XEUtils.clone(tableFullData, true)
366
+ this.tableSourceData = XEUtils.clone(fullData, true)
342
367
  }
343
- this.scrollYLoad = scrollYLoad
344
368
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
345
- if (scrollYLoad) {
369
+ if (sYLoad) {
346
370
  if (!(this.height || this.maxHeight)) {
347
371
  UtilTools.error('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}'])
348
372
  }
@@ -368,8 +392,8 @@ const Methods = {
368
392
  }).then(() => {
369
393
  this.computeScrollLoad()
370
394
  }).then(() => {
371
- // 是否加载了数据
372
- if (scrollYLoad) {
395
+ // 是否启用了虚拟滚动
396
+ if (sYLoad) {
373
397
  scrollYStore.endIndex = scrollYStore.visibleSize
374
398
  }
375
399
  this.handleReserveStatus()
@@ -379,7 +403,7 @@ const Methods = {
379
403
  .then(() => this.recalculate())
380
404
  .then(() => {
381
405
  // 是否变更虚拟滚动
382
- if (oldScrollYLoad === scrollYLoad) {
406
+ if (oldScrollYLoad === sYLoad) {
383
407
  restoreScrollLocation(this, lastScrollLeft, lastScrollTop).then(resolve)
384
408
  } else {
385
409
  setTimeout(() => restoreScrollLocation(this, lastScrollLeft, lastScrollTop).then(resolve))
@@ -446,7 +470,7 @@ const Methods = {
446
470
  tableSourceData[rowIndex] = record
447
471
  XEUtils.clear(row, undefined)
448
472
  Object.assign(row, this.defineField(Object.assign({}, record)))
449
- this.updateCache(true)
473
+ this.cacheRowMap(true)
450
474
  } else {
451
475
  XEUtils.destructuring(oRow, XEUtils.clone(row, true))
452
476
  }
@@ -509,12 +533,12 @@ const Methods = {
509
533
  * 更新数据行的 Map
510
534
  * 牺牲数据组装的耗时,用来换取使用过程中的流畅
511
535
  */
512
- updateCache (source) {
536
+ cacheRowMap (source) {
513
537
  const { treeConfig, treeOpts, tableFullData, fullDataRowMap, fullAllDataRowMap } = this
514
538
  let { fullDataRowIdData, fullAllDataRowIdData } = this
515
539
  const rowkey = getRowkey(this)
516
540
  const isLazy = treeConfig && treeOpts.lazy
517
- const handleCache = (row, index, items, path, parent) => {
541
+ const handleCache = (row, index, items, path, parent, nodes) => {
518
542
  let rowid = getRowid(this, row)
519
543
  if (eqEmptyValue(rowid)) {
520
544
  rowid = getRowUniqueId()
@@ -523,7 +547,7 @@ const Methods = {
523
547
  if (isLazy && row[treeOpts.hasChild] && XEUtils.isUndefined(row[treeOpts.children])) {
524
548
  row[treeOpts.children] = null
525
549
  }
526
- const rest = { row, rowid, index: treeConfig && parent ? -1 : index, items, parent }
550
+ const rest = { row, rowid, index: treeConfig && parent ? -1 : index, items, parent, level: nodes ? nodes.length - 1 : 0 }
527
551
  if (source) {
528
552
  fullDataRowIdData[rowid] = rest
529
553
  fullDataRowMap.set(row, rest)
@@ -543,10 +567,12 @@ const Methods = {
543
567
  tableFullData.forEach(handleCache)
544
568
  }
545
569
  },
546
- loadChildren (row, childRecords) {
570
+ loadTreeChildren (row, childRecords) {
571
+ const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData } = this
572
+ const { children } = treeOpts
573
+ const rest = fullAllDataRowIdData[getRowid(this, row)]
574
+ const parentLevel = rest ? rest.level : 0
547
575
  return this.createData(childRecords).then((rows) => {
548
- const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData } = this
549
- const { children } = treeOpts
550
576
  if (keepSource) {
551
577
  const rowid = getRowid(this, row)
552
578
  const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid(this, item), treeOpts)
@@ -554,9 +580,9 @@ const Methods = {
554
580
  matchObj.item[children] = XEUtils.clone(rows, true)
555
581
  }
556
582
  }
557
- XEUtils.eachTree(rows, (childRow, index, items, path, parent) => {
583
+ XEUtils.eachTree(rows, (childRow, index, items, path, parent, nodes) => {
558
584
  const rowid = getRowid(this, childRow)
559
- const rest = { row: childRow, rowid, index: -1, items, parent }
585
+ const rest = { row: childRow, rowid, index: -1, items, parent, level: parentLevel + nodes.length }
560
586
  fullDataRowIdData[rowid] = rest
561
587
  fullDataRowMap.set(childRow, rest)
562
588
  fullAllDataRowIdData[rowid] = rest
@@ -2375,10 +2401,10 @@ const Methods = {
2375
2401
  triggerHeaderHelpEvent (evnt, params) {
2376
2402
  const { column } = params
2377
2403
  const { titleHelp } = column
2378
- if (titleHelp.message) {
2404
+ if (titleHelp.content || titleHelp.message) {
2379
2405
  const { $refs, tooltipStore } = this
2380
2406
  const tooltip = $refs.tooltip
2381
- const content = UtilTools.getFuncText(titleHelp.message)
2407
+ const content = UtilTools.getFuncText(titleHelp.content || titleHelp.message)
2382
2408
  this.handleTargetEnterEvent()
2383
2409
  tooltipStore.visible = true
2384
2410
  if (tooltip) {
@@ -3458,10 +3484,10 @@ const Methods = {
3458
3484
  return this.$nextTick()
3459
3485
  },
3460
3486
  /**
3461
- * 重新加载展开行的内容
3487
+ * 重新懒加载展开行,并展开内容
3462
3488
  * @param {Row} row 行对象
3463
3489
  */
3464
- reloadExpandContent (row) {
3490
+ reloadRowExpand (row) {
3465
3491
  const { expandOpts, expandLazyLoadeds } = this
3466
3492
  const { lazy } = expandOpts
3467
3493
  if (lazy && expandLazyLoadeds.indexOf(row) === -1) {
@@ -3470,6 +3496,13 @@ const Methods = {
3470
3496
  }
3471
3497
  return this.$nextTick()
3472
3498
  },
3499
+ reloadExpandContent (row) {
3500
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3501
+ UtilTools.warn('vxe.error.delFunc', ['reloadExpandContent', 'reloadRowExpand'])
3502
+ }
3503
+ // 即将废弃
3504
+ return this.reloadRowExpand(row)
3505
+ },
3473
3506
  /**
3474
3507
  * 展开行事件
3475
3508
  */
@@ -3650,18 +3683,32 @@ const Methods = {
3650
3683
  return this.$nextTick()
3651
3684
  },
3652
3685
  /**
3653
- * 重新加载树的子节点
3686
+ * 重新懒加载树节点,并展开该节点
3654
3687
  * @param {Row} row 行对象
3655
3688
  */
3656
- reloadTreeChilds (row) {
3689
+ reloadTreeExpand (row) {
3657
3690
  const { treeOpts, treeLazyLoadeds } = this
3658
- const { lazy, hasChild } = treeOpts
3691
+ const { transform, lazy, hasChild } = treeOpts
3659
3692
  if (lazy && row[hasChild] && treeLazyLoadeds.indexOf(row) === -1) {
3660
- this.clearTreeExpandLoaded(row)
3661
- .then(() => this.handleAsyncTreeExpandChilds(row))
3693
+ this.clearTreeExpandLoaded(row).then(() => {
3694
+ return this.handleAsyncTreeExpandChilds(row)
3695
+ }).then(() => {
3696
+ if (transform) {
3697
+ return this.updateVirtualTreeData()
3698
+ }
3699
+ }).then(() => {
3700
+ return this.recalculate()
3701
+ })
3662
3702
  }
3663
3703
  return this.$nextTick()
3664
3704
  },
3705
+ reloadTreeChilds (row) {
3706
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3707
+ UtilTools.warn('vxe.error.delFunc', ['reloadTreeChilds', 'reloadTreeExpand'])
3708
+ }
3709
+ // 即将废弃
3710
+ return this.reloadTreeExpand(row)
3711
+ },
3665
3712
  /**
3666
3713
  * 展开树节点事件
3667
3714
  */
@@ -3719,7 +3766,7 @@ const Methods = {
3719
3766
  childRecords = []
3720
3767
  }
3721
3768
  if (childRecords) {
3722
- this.loadChildren(row, childRecords).then(childRows => {
3769
+ this.loadTreeChildren(row, childRecords).then(childRows => {
3723
3770
  if (childRows.length && treeExpandeds.indexOf(row) === -1) {
3724
3771
  treeExpandeds.push(row)
3725
3772
  }
@@ -3749,6 +3796,78 @@ const Methods = {
3749
3796
  }, treeOpts)
3750
3797
  return this.setTreeExpand(expandeds, expanded)
3751
3798
  },
3799
+ /**
3800
+ * 默认,展开与收起树节点
3801
+ * @param rows
3802
+ * @param expanded
3803
+ * @returns
3804
+ */
3805
+ handleBaseTreeExpand (rows, expanded) {
3806
+ const { fullAllDataRowMap, tableFullData, treeExpandeds, treeOpts, treeLazyLoadeds, treeNodeColumn } = this
3807
+ const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3808
+ const result = []
3809
+ const columnIndex = this.getColumnIndex(treeNodeColumn)
3810
+ const $columnIndex = this.getVMColumnIndex(treeNodeColumn)
3811
+ let validRows = toggleMethod ? rows.filter(row => toggleMethod({ expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3812
+ if (accordion) {
3813
+ validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3814
+ // 同一级只能展开一个
3815
+ const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3816
+ if (matchObj) {
3817
+ XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3818
+ }
3819
+ }
3820
+ if (expanded) {
3821
+ validRows.forEach(row => {
3822
+ if (treeExpandeds.indexOf(row) === -1) {
3823
+ const rest = fullAllDataRowMap.get(row)
3824
+ const isLoad = lazy && row[hasChild] && !rest.treeLoaded && treeLazyLoadeds.indexOf(row) === -1
3825
+ // 是否使用懒加载
3826
+ if (isLoad) {
3827
+ result.push(this.handleAsyncTreeExpandChilds(row))
3828
+ } else {
3829
+ if (row[children] && row[children].length) {
3830
+ treeExpandeds.push(row)
3831
+ }
3832
+ }
3833
+ }
3834
+ })
3835
+ } else {
3836
+ XEUtils.remove(treeExpandeds, row => validRows.indexOf(row) > -1)
3837
+ }
3838
+ if (reserve) {
3839
+ validRows.forEach(row => this.handleTreeExpandReserve(row, expanded))
3840
+ }
3841
+ return Promise.all(result).then(this.recalculate)
3842
+ },
3843
+ updateVirtualTreeData () {
3844
+ const { scrollYLoad: oldScrollYLoad, treeExpandeds, treeOpts, treeFullData } = this
3845
+ const fullData = []
3846
+ XEUtils.eachTree(treeFullData, (row, index, items, path, parent) => {
3847
+ if (!parent || treeExpandeds.indexOf(parent) > -1) {
3848
+ fullData.push(row)
3849
+ }
3850
+ }, treeOpts)
3851
+ const scrollYLoad = this.updateScrollYStatus(fullData)
3852
+ this.tableFullData = scrollYLoad ? fullData : treeFullData
3853
+ if (scrollYLoad || oldScrollYLoad !== scrollYLoad) {
3854
+ return this.handleTableData(true).then(() => this.recalculate())
3855
+ }
3856
+ return this.$nextTick()
3857
+ },
3858
+ /**
3859
+ * 虚拟树的展开与收起
3860
+ * @param rows
3861
+ * @param expanded
3862
+ * @returns
3863
+ */
3864
+ handleVirtualTreeExpand (rows, expanded) {
3865
+ return this.handleBaseTreeExpand(rows, expanded).then(() => {
3866
+ return this.updateVirtualTreeData()
3867
+ }).then(() => {
3868
+ return this.recalculate()
3869
+ })
3870
+ },
3752
3871
  /**
3753
3872
  * 设置展开树形节点,二个参数设置这一行展开与否
3754
3873
  * 支持单行
@@ -3757,47 +3876,19 @@ const Methods = {
3757
3876
  * @param {Boolean} expanded 是否展开
3758
3877
  */
3759
3878
  setTreeExpand (rows, expanded) {
3760
- const { fullAllDataRowMap, tableFullData, treeExpandeds, treeOpts, treeLazyLoadeds, treeNodeColumn } = this
3761
- const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3762
- const result = []
3763
- const columnIndex = this.getColumnIndex(treeNodeColumn)
3764
- const $columnIndex = this.getVMColumnIndex(treeNodeColumn)
3879
+ const { treeOpts } = this
3880
+ const { transform } = treeOpts
3765
3881
  if (rows) {
3766
3882
  if (!XEUtils.isArray(rows)) {
3767
3883
  rows = [rows]
3768
3884
  }
3769
3885
  if (rows.length) {
3770
- let validRows = toggleMethod ? rows.filter(row => toggleMethod({ expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3771
- if (accordion) {
3772
- validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3773
- // 同一级只能展开一个
3774
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3775
- if (matchObj) {
3776
- XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3777
- }
3778
- }
3779
- if (expanded) {
3780
- validRows.forEach(row => {
3781
- if (treeExpandeds.indexOf(row) === -1) {
3782
- const rest = fullAllDataRowMap.get(row)
3783
- const isLoad = lazy && row[hasChild] && !rest.treeLoaded && treeLazyLoadeds.indexOf(row) === -1
3784
- // 是否使用懒加载
3785
- if (isLoad) {
3786
- result.push(this.handleAsyncTreeExpandChilds(row))
3787
- } else {
3788
- if (row[children] && row[children].length) {
3789
- treeExpandeds.push(row)
3790
- }
3791
- }
3792
- }
3793
- })
3886
+ // 如果为虚拟树
3887
+ if (transform) {
3888
+ return this.handleVirtualTreeExpand(rows, expanded)
3794
3889
  } else {
3795
- XEUtils.remove(treeExpandeds, row => validRows.indexOf(row) > -1)
3796
- }
3797
- if (reserve) {
3798
- validRows.forEach(row => this.handleTreeExpandReserve(row, expanded))
3890
+ return this.handleBaseTreeExpand(rows, expanded)
3799
3891
  }
3800
- return Promise.all(result).then(this.recalculate)
3801
3892
  }
3802
3893
  }
3803
3894
  return this.$nextTick()
@@ -3820,7 +3911,7 @@ const Methods = {
3820
3911
  if (reserve) {
3821
3912
  XEUtils.eachTree(tableFullData, row => this.handleTreeExpandReserve(row, false), treeOpts)
3822
3913
  }
3823
- return this.$nextTick().then(() => {
3914
+ return this.updateVirtualTreeData().then(() => {
3824
3915
  if (isExists) {
3825
3916
  this.recalculate()
3826
3917
  }
@@ -4333,6 +4424,15 @@ const funcs = 'setFilter,clearFilter,getCheckedFilters,closeMenu,setActiveCellAr
4333
4424
 
4334
4425
  funcs.forEach(name => {
4335
4426
  Methods[name] = function (...args) {
4427
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
4428
+ if (!this[`_${name}`]) {
4429
+ if ('openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',').includes(name)) {
4430
+ UtilTools.error('vxe.error.reqModule', ['Export'])
4431
+ } else if ('clearValidate,fullValidate,validate'.split(',').includes(name)) {
4432
+ UtilTools.error('vxe.error.reqModule', ['Validator'])
4433
+ }
4434
+ }
4435
+ }
4336
4436
  return this[`_${name}`] ? this[`_${name}`](...args) : null
4337
4437
  }
4338
4438
  })
@@ -179,8 +179,11 @@ export default {
179
179
  autoResize: { type: Boolean, default: () => GlobalConfig.table.autoResize },
180
180
  // 是否自动根据状态属性去更新响应式表格宽高
181
181
  syncResize: [Boolean, String, Number],
182
- // 设置列的默认参数,仅对部分支持的属性有效
182
+ // 列配置信息
183
183
  columnConfig: Object,
184
+ // 行配置信息
185
+ rowConfig: Object,
186
+ // 列调整配置项
184
187
  resizableConfig: Object,
185
188
  // 序号配置项
186
189
  seqConfig: Object,
@@ -453,7 +456,10 @@ export default {
453
456
  }
454
457
  },
455
458
  columnOpts () {
456
- return Object.assign({}, this.columnConfig)
459
+ return Object.assign({}, GlobalConfig.table.columnConfig, this.columnConfig)
460
+ },
461
+ rowOpts () {
462
+ return Object.assign({}, GlobalConfig.table.rowConfig, this.rowConfig)
457
463
  },
458
464
  resizableOpts () {
459
465
  return Object.assign({}, GlobalConfig.table.resizableConfig, this.resizableConfig)
@@ -780,6 +786,9 @@ export default {
780
786
  if (this.treeConfig && this.checkboxOpts.range) {
781
787
  UtilTools.error('vxe.error.noTree', ['checkbox-config.range'])
782
788
  }
789
+ if (this.rowOpts.height && !this.showOverflow) {
790
+ UtilTools.warn('vxe.error.notProp', ['table.show-overflow'])
791
+ }
783
792
  if (!this.handleUpdateCellAreas) {
784
793
  if (this.clipConfig) {
785
794
  UtilTools.warn('vxe.error.notProp', ['clip-config'])
@@ -9,6 +9,7 @@ export default {
9
9
  table: {
10
10
  fit: true,
11
11
  showHeader: true,
12
+ animat: true,
12
13
  delayHover: 250,
13
14
  // keepSource: false,
14
15
  // showOverflow: null,
@@ -17,7 +18,6 @@ export default {
17
18
  // resizeInterval: 500,
18
19
  // size: null,
19
20
  // zIndex: null,
20
- // resizable: false,
21
21
  // autoResize: false,
22
22
  // stripe: false,
23
23
  // border: false,
@@ -63,8 +63,8 @@ export default {
63
63
  showIcon: true
64
64
  },
65
65
  treeConfig: {
66
- rowtKey: 'id',
67
- parentKey: 'parentId',
66
+ rowField: 'id',
67
+ parentField: 'parentId',
68
68
  children: 'children',
69
69
  hasChild: 'hasChild',
70
70
  indent: 20,