n20-common-lib 2.22.48 → 2.22.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n20-common-lib",
3
- "version": "2.22.48",
3
+ "version": "2.22.50",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -828,7 +828,15 @@ export default {
828
828
  showClose: true
829
829
  })
830
830
  }
831
- this.$emit('delete-rows', this.selectionList)
831
+ this.$msgboxPor({
832
+ title: $lc('确认删除所选附件吗?'),
833
+ message: $lc('删除后数据不可恢复'),
834
+ type: 'error',
835
+ confirmButtonText: $lc('确认'),
836
+ cancelButtonText: $lc('取消')
837
+ }).then(() => {
838
+ this.$emit('delete-rows', this.selectionList)
839
+ }).catch(() => undefined)
832
840
  },
833
841
 
834
842
  async getFileInfo(row, type) {
@@ -0,0 +1,60 @@
1
+ let vxeVersion = ''
2
+
3
+ export function getVxeCore(vxe) {
4
+ return vxe && (vxe.VXETable || vxe.default || vxe)
5
+ }
6
+
7
+ export function setVxeVersion(version) {
8
+ vxeVersion = version || ''
9
+ }
10
+
11
+ export function getVxeVersion() {
12
+ return vxeVersion
13
+ }
14
+
15
+ export function compareVersion(version, target) {
16
+ const versionParts = `${version}`.split('.').map((item) => Number.parseInt(item, 10) || 0)
17
+ const targetParts = `${target}`.split('.').map((item) => Number.parseInt(item, 10) || 0)
18
+ const len = Math.max(versionParts.length, targetParts.length)
19
+ for (let i = 0; i < len; i++) {
20
+ const current = versionParts[i] || 0
21
+ const next = targetParts[i] || 0
22
+ if (current > next) return 1
23
+ if (current < next) return -1
24
+ }
25
+ return 0
26
+ }
27
+
28
+ export function isVxe320OrNewer() {
29
+ return compareVersion(vxeVersion, '3.20.0') >= 0
30
+ }
31
+
32
+ export function resolveMaybeFunction(value) {
33
+ return typeof value === 'function' ? value() : value
34
+ }
35
+
36
+ export function normalizeArray(value) {
37
+ const resolved = resolveMaybeFunction(value)
38
+ return Array.isArray(resolved) ? resolved : []
39
+ }
40
+
41
+ export function getColumnField(column) {
42
+ if (!column) return undefined
43
+ return column.field || column.property
44
+ }
45
+
46
+ export function getEventField(params) {
47
+ if (!params) return undefined
48
+ return params.field || params.property || getColumnField(params.column)
49
+ }
50
+
51
+ export function getRowValue(row, field) {
52
+ if (!row || !field) return undefined
53
+ if (Object.prototype.hasOwnProperty.call(row, field)) {
54
+ return row[field]
55
+ }
56
+ return `${field}`.split('.').reduce((value, key) => {
57
+ if (value === undefined || value === null) return undefined
58
+ return value[key]
59
+ }, row)
60
+ }
@@ -5,11 +5,28 @@ import numerify from 'numerify'
5
5
  import dayjs from 'dayjs'
6
6
  import { $lc } from '../../utils/i18n/index.js'
7
7
  import zhCN from 'vxe-table/lib/locale/lang/zh-CN'
8
+ import { getColumnField, getRowValue, getVxeCore, setVxeVersion } from './compat.js'
9
+
10
+ function getInstalledVxeVersion(vxe) {
11
+ const core = getVxeCore(vxe)
12
+ return (
13
+ (vxe && (vxe.tableVersion || vxe.version)) ||
14
+ (core && (core.tableVersion || core.version)) ||
15
+ ''
16
+ )
17
+ }
18
+
19
+ setVxeVersion(getInstalledVxeVersion(vxeTable))
20
+ const vxeCore = getVxeCore(vxeTable)
21
+ const setupVxeTable = (vxeTable && vxeTable.setup) || (vxeCore && vxeCore.setup)
22
+ const vxeRenderer = (vxeTable && vxeTable.renderer) || (vxeCore && vxeCore.renderer)
23
+ const vxeFormats = (vxeTable && vxeTable.formats) || (vxeCore && vxeCore.formats)
24
+
8
25
  // 打平对象
9
26
  function flattenObject(obj, prefix = '', result = {}) {
10
27
  // 遍历对象的每个属性
11
28
  for (const key in obj) {
12
- if (obj.hasOwnProperty(key)) {
29
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
13
30
  // 构建当前属性的完整键名
14
31
  const fullKey = prefix ? `${prefix}.${key}` : key
15
32
 
@@ -24,103 +41,110 @@ function flattenObject(obj, prefix = '', result = {}) {
24
41
  }
25
42
  return result
26
43
  }
27
- vxeTable.setup({
28
- size: 'small',
29
- table: {
30
- border: true,
31
- align: 'center',
32
- columnConfig: {
33
- resizable: true
44
+ if (typeof setupVxeTable === 'function') {
45
+ setupVxeTable.call(vxeCore || vxeTable, {
46
+ size: 'small',
47
+ table: {
48
+ border: true,
49
+ align: 'center',
50
+ columnConfig: {
51
+ resizable: true
52
+ }
53
+ },
54
+ // 对组件内置的提示语进行国际化翻译
55
+ i18n: (key, args) => {
56
+ return $lc(flattenObject(zhCN) && flattenObject(zhCN)[key])
34
57
  }
35
- },
36
- // 对组件内置的提示语进行国际化翻译
37
- i18n: (key, args) => {
38
- return $lc(flattenObject(zhCN) && flattenObject(zhCN)[key])
39
- }
40
- })
58
+ })
59
+ }
41
60
  // 创建一个简单的输入框筛选
42
- vxeTable.renderer.add('FilterInput', {
61
+ if (vxeRenderer && typeof vxeRenderer.add === 'function') {
62
+ vxeRenderer.add('FilterInput', {
43
63
  // 筛选模板
44
- renderFilter(h, renderOpts, params) {
45
- return <filterContent params={params}></filterContent>
46
- },
47
- // 不显示底部按钮,使用自定义的按钮
48
- showFilterFooter: false,
49
- // 重置数据方法
50
- filterResetMethod({ options }) {
51
- options.forEach((option) => {
64
+ renderFilter(h, renderOpts, params) {
65
+ return <filterContent params={params}></filterContent>
66
+ },
67
+ // 不显示底部按钮,使用自定义的按钮
68
+ showFilterFooter: false,
69
+ // 重置数据方法
70
+ filterResetMethod({ options }) {
71
+ options.forEach((option) => {
72
+ option.data = ''
73
+ })
74
+ },
75
+ // 重置筛选复原方法(当未点击确认时,该选项将被恢复为默认值)
76
+ filterRecoverMethod({ option }) {
52
77
  option.data = ''
53
- })
54
- },
55
- // 重置筛选复原方法(当未点击确认时,该选项将被恢复为默认值)
56
- filterRecoverMethod({ option }) {
57
- option.data = ''
58
- },
59
- // 筛选方法
60
- filterMethod({ option, row, column }) {
61
- const { data } = option
62
- const cellValue = row[column.property]
63
- if (cellValue) {
64
- return cellValue.indexOf(data) > -1
78
+ },
79
+ // 筛选方法
80
+ filterMethod({ option, row, column }) {
81
+ const { data } = option
82
+ const field = getColumnField(column)
83
+ const cellValue = getRowValue(row, field)
84
+ if (cellValue !== undefined && cellValue !== null) {
85
+ return `${cellValue}`.indexOf(data) > -1
86
+ }
87
+ return false
65
88
  }
66
- return false
67
- }
68
- })
89
+ })
90
+ }
69
91
 
70
92
  // 自定义全局的格式化处理函数
71
- vxeTable.formats.mixin({
72
- // 格式化内容 为空转为--
73
- formatName({ cellValue }) {
74
- return cellValue || '--'
75
- },
76
- // 格式化性别
77
- formatSex({ cellValue }) {
78
- return cellValue ? (cellValue === '1' ? '男' : '女') : '--'
79
- },
80
- // 格式化下拉选项
81
- formatSelect({ cellValue }, list) {
82
- const item = list.find((item) => item.value === cellValue)
83
- return item ? item.label : '--'
84
- },
85
- // 格式化日期,默认 yyyy-MM-dd
86
- formatDate({ cellValue }) {
87
- if (cellValue) {
88
- return dayjs(cellValue).format('YYYY-MM-DD')
89
- } else {
90
- return '--'
91
- }
92
- },
93
- // 四舍五入金额,每隔3位逗号分隔,默认2位数
94
- formatAmount({ cellValue }) {
95
- if (cellValue || cellValue === 0) {
96
- // 判断是否为字符串类数字
97
- if (/^-?\d+(\.\d+)?$/.test(cellValue)) {
98
- return numerify(cellValue, '0,0.00')
93
+ if (vxeFormats && typeof vxeFormats.mixin === 'function') {
94
+ vxeFormats.mixin({
95
+ // 格式化内容 为空转为--
96
+ formatName({ cellValue }) {
97
+ return cellValue || '--'
98
+ },
99
+ // 格式化性别
100
+ formatSex({ cellValue }) {
101
+ return cellValue ? (cellValue === '1' ? '男' : '女') : '--'
102
+ },
103
+ // 格式化下拉选项
104
+ formatSelect({ cellValue }, list) {
105
+ const item = list.find((item) => item.value === cellValue)
106
+ return item ? item.label : '--'
107
+ },
108
+ // 格式化日期,默认 yyyy-MM-dd
109
+ formatDate({ cellValue }) {
110
+ if (cellValue) {
111
+ return dayjs(cellValue).format('YYYY-MM-DD')
99
112
  } else {
100
- return cellValue
113
+ return '--'
114
+ }
115
+ },
116
+ // 四舍五入金额,每隔3位逗号分隔,默认2位数
117
+ formatAmount({ cellValue }) {
118
+ if (cellValue || cellValue === 0) {
119
+ // 判断是否为字符串类数字
120
+ if (/^-?\d+(\.\d+)?$/.test(cellValue)) {
121
+ return numerify(cellValue, '0,0.00')
122
+ } else {
123
+ return cellValue
124
+ }
125
+ // return numerify(cellValue, '0,0.00')
126
+ } else {
127
+ return '--'
128
+ }
129
+ },
130
+ // 利率
131
+ formatRate({ cellValue }) {
132
+ if (cellValue || cellValue === 0) {
133
+ return numerify(cellValue, '0.000000')
134
+ } else {
135
+ return '--'
136
+ }
137
+ },
138
+ // 格式化时间,默认 yyyy-MM-dd HH:mm:ss
139
+ formatDatetime({ cellValue }) {
140
+ if (cellValue) {
141
+ return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss')
142
+ } else {
143
+ return '--'
101
144
  }
102
- // return numerify(cellValue, '0,0.00')
103
- } else {
104
- return '--'
105
- }
106
- },
107
- // 利率
108
- formatRate({ cellValue }) {
109
- if (cellValue || cellValue === 0) {
110
- return numerify(cellValue, '0.000000')
111
- } else {
112
- return '--'
113
- }
114
- },
115
- // 格式化时间,默认 yyyy-MM-dd HH:mm:ss
116
- formatDatetime({ cellValue }) {
117
- if (cellValue) {
118
- return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss')
119
- } else {
120
- return '--'
121
145
  }
122
- }
123
- })
146
+ })
147
+ }
124
148
 
125
149
  function install(Vue) {
126
150
  Vue.use(vxeTable)
@@ -16,6 +16,7 @@
16
16
  show-header-overflow
17
17
  show-overflow
18
18
  :row-config="computedRowConfig"
19
+ :cell-config="computedCellConfig"
19
20
  :column-config="{
20
21
  resizable: true,
21
22
  useKey: true,
@@ -23,6 +24,7 @@
23
24
  ...$attrs['column-config']
24
25
  }"
25
26
  :scroll-y="computedScrollY"
27
+ :virtual-y-config="computedVirtualYConfig"
26
28
  :sort-config="{
27
29
  multiple: false,
28
30
  remote: true,
@@ -139,6 +141,7 @@
139
141
  import empty from '../Empty'
140
142
  import tableSetSize from '../TableSetSize/index.vue'
141
143
  import { $lc } from '../../utils/i18n/index.js'
144
+ import { getColumnField, getEventField, isVxe320OrNewer, normalizeArray } from './compat.js'
142
145
 
143
146
  /** 将 Element 表格风格的 show-overflow-tooltip 转为 vxe-column 的 show-overflow */
144
147
  function hasOverflowTooltipKey(item) {
@@ -183,12 +186,14 @@ function mapColumnOverflowForVxe(item) {
183
186
  // vxe-table 3.6 在渲染行数超过 40 时会防抖更新虚拟滚动数据,快速滚动容易露出空白。
184
187
  // 保持较小的默认缓冲,让常见高度下走同步更新路径;业务仍可通过 scroll-y.oSize 覆盖。
185
188
  const DEFAULT_SCROLL_Y = { enabled: true, oSize: 6, gt: 30 }
189
+ const DEFAULT_VIRTUAL_Y = { ...DEFAULT_SCROLL_Y, preSize: 1, immediate: true }
186
190
  const VXE_ROW_HEIGHT_MAP = {
187
191
  default: 48,
188
192
  medium: 44,
189
193
  small: 40,
190
194
  mini: 36
191
195
  }
196
+
192
197
  const renderer = {
193
198
  name: 'renderer',
194
199
  props: {
@@ -217,6 +222,10 @@ export default {
217
222
  return { ...DEFAULT_SCROLL_Y }
218
223
  }
219
224
  },
225
+ virtualYConfig: {
226
+ type: Object,
227
+ default: undefined
228
+ },
220
229
  dynamicRowHeight: {
221
230
  type: Boolean,
222
231
  default: false
@@ -296,8 +305,12 @@ export default {
296
305
  const small = attrs.small
297
306
  delete attrs.rowConfig
298
307
  delete attrs['row-config']
308
+ delete attrs.cellConfig
309
+ delete attrs['cell-config']
299
310
  delete attrs.scrollY
300
311
  delete attrs['scroll-y']
312
+ delete attrs.virtualYConfig
313
+ delete attrs['virtual-y-config']
301
314
  delete attrs.small
302
315
  return Object.assign({ size: this.sizeC || this.size }, attrs, this.sizeBind, small)
303
316
  },
@@ -311,12 +324,31 @@ export default {
311
324
  ...this.$attrs.rowConfig,
312
325
  ...this.$attrs['row-config']
313
326
  }
314
- if (!this.dynamicRowHeight && rowConfig.height === undefined) {
327
+ const isVxe320 = isVxe320OrNewer()
328
+ if (!this.dynamicRowHeight && !isVxe320 && rowConfig.height === undefined) {
315
329
  rowConfig.height = this.getVirtualRowHeight()
316
330
  }
331
+ if (isVxe320) {
332
+ delete rowConfig.height
333
+ }
317
334
  return rowConfig
318
335
  },
336
+ computedCellConfig() {
337
+ const cellConfig = {
338
+ ...this.$attrs.cellConfig,
339
+ ...this.$attrs['cell-config']
340
+ }
341
+ const hasCellConfig = Object.keys(cellConfig).length > 0
342
+ if (!isVxe320OrNewer()) {
343
+ return hasCellConfig ? cellConfig : undefined
344
+ }
345
+ if (!this.dynamicRowHeight && cellConfig.height === undefined) {
346
+ cellConfig.height = this.getVirtualRowHeight()
347
+ }
348
+ return cellConfig
349
+ },
319
350
  computedScrollY() {
351
+ if (isVxe320OrNewer()) return undefined
320
352
  const scrollY = {
321
353
  ...DEFAULT_SCROLL_Y,
322
354
  ...(this.scrollY || {})
@@ -330,6 +362,24 @@ export default {
330
362
  }
331
363
  return scrollY
332
364
  },
365
+ computedVirtualYConfig() {
366
+ const attrVirtualYConfig = {
367
+ ...this.$attrs.virtualYConfig,
368
+ ...this.$attrs['virtual-y-config']
369
+ }
370
+ if (!isVxe320OrNewer()) return undefined
371
+ const virtualYConfig = {
372
+ ...DEFAULT_VIRTUAL_Y,
373
+ ...(this.scrollY || {}),
374
+ ...attrVirtualYConfig,
375
+ ...(this.virtualYConfig || {})
376
+ }
377
+ delete virtualYConfig.rHeight
378
+ if (this.dynamicRowHeight) {
379
+ virtualYConfig.enabled = false
380
+ }
381
+ return virtualYConfig
382
+ },
333
383
  _columns() {
334
384
  const raw = this.isAutoWidth ? this.calcColumnWidth(this.columns) : this.columns
335
385
  return raw.map(mapColumnOverflowForVxe)
@@ -347,30 +397,45 @@ export default {
347
397
  data() {
348
398
  // 翻页清除选中
349
399
  if (this.clearSelect) {
350
- this.$refs.vxeTable.clearCheckboxRow()
400
+ this.callTableMethod('clearCheckboxRow')
351
401
  this.$emit('selection-change-method', [])
352
402
  }
353
403
  // 数据更新后重新设置合并单元格
354
404
  this.$nextTick(() => {
355
405
  if (this.mergeCells && this.mergeCells.length > 0 && this.$refs.vxeTable) {
356
- this.$refs.vxeTable.setMergeCells(this.mergeCells)
406
+ this.callTableMethod('setMergeCells', this.mergeCells)
357
407
  }
358
408
  this.refreshTableLayout()
359
409
  })
360
410
  }
361
411
  },
362
412
  activated() {
363
- this.$refs.vxeTable.loadData(this.data)
413
+ this.callTableMethod('loadData', this.data)
364
414
  // 数据更新后重新设置合并单元格
365
415
  this.$nextTick(() => {
366
416
  if (this.mergeCells && this.mergeCells.length > 0 && this.$refs.vxeTable) {
367
- this.$refs.vxeTable.setMergeCells(this.mergeCells)
417
+ this.callTableMethod('setMergeCells', this.mergeCells)
368
418
  }
369
419
  this.refreshTableLayout()
370
420
  })
371
421
  },
372
422
  methods: {
423
+ callTableMethod(methodName, ...args) {
424
+ const xTable = this.$refs.vxeTable
425
+ if (!xTable || typeof xTable[methodName] !== 'function') return undefined
426
+ return xTable[methodName](...args)
427
+ },
428
+ getTableRows(methodName, ...args) {
429
+ return normalizeArray(this.callTableMethod(methodName, ...args))
430
+ },
373
431
  getVirtualRowHeight() {
432
+ const cellConfig = {
433
+ ...this.$attrs.cellConfig,
434
+ ...this.$attrs['cell-config']
435
+ }
436
+ if (cellConfig.height !== undefined) {
437
+ return cellConfig.height
438
+ }
374
439
  const rowConfig = {
375
440
  ...this.$attrs.rowConfig,
376
441
  ...this.$attrs['row-config']
@@ -410,18 +475,18 @@ export default {
410
475
  return true
411
476
  })
412
477
  // 判断当前可选行是否已全部选中
413
- const checkedRows = this.$refs.vxeTable.getCheckboxRecords(false)
478
+ const checkedRows = this.getTableRows('getCheckboxRecords', false)
414
479
  const checkedSet = new Set(checkedRows)
415
480
  const isAllChecked = selectableRows.length > 0 && selectableRows.every((row) => checkedSet.has(row))
416
481
  if (isAllChecked) {
417
482
  // 已全选,则取消可选行的选中状态
418
483
  selectableRows.forEach((row) => {
419
- this.$refs.vxeTable.setCheckboxRow(row, false)
484
+ this.callTableMethod('setCheckboxRow', row, false)
420
485
  })
421
486
  } else {
422
487
  // 未全选,则选中所有可选行
423
488
  selectableRows.forEach((row) => {
424
- this.$refs.vxeTable.setCheckboxRow(row, true)
489
+ this.callTableMethod('setCheckboxRow', row, true)
425
490
  })
426
491
  }
427
492
  // 得手动触发
@@ -446,14 +511,14 @@ export default {
446
511
  // 清空选择
447
512
  clearSelection() {
448
513
  if (this.$refs.vxeTable) {
449
- this.$refs.vxeTable.setAllCheckboxRow(false)
514
+ this.callTableMethod('setAllCheckboxRow', false)
450
515
  // 得手动触发
451
516
  this.handleSelectionChange()
452
517
  }
453
518
  },
454
519
  // 选中某些行
455
520
  toggleRowSelection(row, state = true) {
456
- this.$refs.vxeTable.setCheckboxRow(row, state)
521
+ this.callTableMethod('setCheckboxRow', row, state)
457
522
  // 得手动触发
458
523
  this.handleSelectionChange()
459
524
  },
@@ -472,7 +537,7 @@ export default {
472
537
  return true
473
538
  })
474
539
  // 判断当前可选行是否已全部选中
475
- const checkedRows = $table.getCheckboxRecords(false)
540
+ const checkedRows = normalizeArray($table.getCheckboxRecords(false))
476
541
  const checkedSet = new Set(checkedRows)
477
542
  const isAllChecked = selectableRows.length > 0 && selectableRows.every((row) => checkedSet.has(row))
478
543
  if (isAllChecked) {
@@ -501,17 +566,17 @@ export default {
501
566
  this.key++
502
567
  this.handleSelectionChange(row)
503
568
  },
504
- customSortMethod({ sortList }) {
505
- const orders = sortList.map((item) => {
569
+ customSortMethod(data = {}) {
570
+ const orders = normalizeArray(data.sortList).map((item) => {
506
571
  return {
507
- column: item.field,
572
+ column: getEventField(item) || getColumnField(item.column),
508
573
  asc: item.order === 'asc'
509
574
  }
510
575
  })
511
576
  this.$emit('sort-change-method', orders)
512
577
  },
513
- filterChange(data) {
514
- const { filterList } = data
578
+ filterChange(data = {}) {
579
+ const filterList = normalizeArray(data.filterList || data.filters)
515
580
  // 输出全部条件
516
581
  const obj = {}
517
582
  // 复制默认筛选条件为空
@@ -521,17 +586,20 @@ export default {
521
586
  }
522
587
  })
523
588
  filterList.forEach((item) => {
524
- if (item.column.filterMultiple) {
525
- this.$set(obj, item.field, item.values)
589
+ const field = getEventField(item)
590
+ if (!field) return
591
+ if (item.column && item.column.filterMultiple) {
592
+ this.$set(obj, field, item.values)
526
593
  } else {
527
- this.$set(obj, item.field, item.values && item.values[0])
594
+ this.$set(obj, field, item.values && item.values[0])
528
595
  }
529
596
  })
530
597
  // 输出单个条件
531
598
  const singleObj = {}
599
+ const currentField = getEventField(data)
532
600
  for (let key in obj) {
533
- if (key === data.field) {
534
- singleObj[data.field] = obj[data.field]
601
+ if (key === currentField) {
602
+ singleObj[currentField] = obj[currentField]
535
603
  }
536
604
  }
537
605
  if (this.isFiliterSingle) {
@@ -542,16 +610,17 @@ export default {
542
610
  },
543
611
  // row当前单次勾选的哪一行数据 包含checked字段
544
612
  handleSelectionChange(row = '') {
545
- const val = this.$refs.vxeTable.getCheckboxRecords()
613
+ const currentRow = row && Object.prototype.hasOwnProperty.call(row, 'row') ? row.row : row
614
+ const val = this.getTableRows('getCheckboxRecords')
546
615
  // 支持跨页勾选
547
- const val1 = this.$refs.vxeTable.getCheckboxReserveRecords()
548
- this.$emit('selection-change-method', [...val, ...val1], row)
616
+ const val1 = this.getTableRows('getCheckboxReserveRecords')
617
+ this.$emit('selection-change-method', [...val, ...val1], currentRow)
549
618
  },
550
619
  // 点击行勾选/取消勾选
551
620
  handleCellClick({ row, column, $event }) {
552
621
  this.$emit('cell-click', { row, column, $event })
553
622
  // 如果点击的是 checkbox 列,不处理(由原生的 checkbox 处理)
554
- if (column.type === 'checkbox') {
623
+ if (column && column.type === 'checkbox') {
555
624
  return
556
625
  }
557
626
 
@@ -563,7 +632,8 @@ export default {
563
632
  // - [class*="button"]: 包含 button 类名的元素
564
633
  // - [class*="el-link--inner"]: Element UI 链接组件内部元素
565
634
  // - a[href]: 链接标签
566
- const target = $event.target
635
+ const target = $event && $event.target
636
+ if (!target) return
567
637
  const clickedButton = target.closest(
568
638
  'button, .el-button, .n20-button, [class*="button"], [class*="el-link--inner"], a[href]'
569
639
  )
@@ -592,7 +662,7 @@ export default {
592
662
 
593
663
  if (canCheck) {
594
664
  // 切换该行的勾选状态
595
- this.$refs.vxeTable.toggleCheckboxRow(row)
665
+ this.callTableMethod('toggleCheckboxRow', row)
596
666
  this.key++ // 强制刷新 checkbox 显示
597
667
  this.handleSelectionChange(row)
598
668
  }