vxe-table 3.19.39 → 3.20.0-beta.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.
Files changed (109) hide show
  1. package/es/index.css +1 -1
  2. package/es/index.esm.js +2 -1
  3. package/es/index.min.css +1 -1
  4. package/es/style.css +1 -1
  5. package/es/style.min.css +1 -1
  6. package/es/table/module/custom/mixin.js +6 -4
  7. package/es/table/module/custom/panel.js +806 -799
  8. package/es/table/module/edit/mixin.js +43 -31
  9. package/es/table/module/export/export-panel.js +511 -458
  10. package/es/table/module/export/import-panel.js +224 -192
  11. package/es/table/module/keyboard/mixin.js +2 -2
  12. package/es/table/module/menu/panel.js +165 -161
  13. package/es/table/module/validator/mixin.js +255 -236
  14. package/es/table/src/body.js +2 -1
  15. package/es/table/src/cell.js +2 -2
  16. package/es/table/src/methods.js +33 -43
  17. package/es/table/src/table.js +13 -249
  18. package/es/table/src/util.js +242 -0
  19. package/es/table/style.css +23 -50
  20. package/es/table/style.min.css +1 -1
  21. package/es/ui/index.js +2 -2
  22. package/es/ui/src/dom.js +22 -0
  23. package/es/ui/src/log.js +1 -1
  24. package/es/vxe-table/style.css +23 -50
  25. package/es/vxe-table/style.min.css +1 -1
  26. package/lib/index.common.js +2 -1
  27. package/lib/index.css +1 -1
  28. package/lib/index.min.css +1 -1
  29. package/lib/index.umd.js +3640 -4790
  30. package/lib/index.umd.min.js +1 -1
  31. package/lib/style.css +1 -1
  32. package/lib/style.min.css +1 -1
  33. package/lib/table/module/custom/mixin.js +6 -4
  34. package/lib/table/module/custom/mixin.min.js +1 -1
  35. package/lib/table/module/custom/panel.js +693 -685
  36. package/lib/table/module/custom/panel.min.js +1 -1
  37. package/lib/table/module/edit/mixin.js +47 -31
  38. package/lib/table/module/edit/mixin.min.js +1 -1
  39. package/lib/table/module/export/export-panel.js +450 -384
  40. package/lib/table/module/export/export-panel.min.js +1 -1
  41. package/lib/table/module/export/import-panel.js +200 -159
  42. package/lib/table/module/export/import-panel.min.js +1 -1
  43. package/lib/table/module/keyboard/mixin.js +2 -2
  44. package/lib/table/module/keyboard/mixin.min.js +1 -1
  45. package/lib/table/module/menu/panel.js +119 -114
  46. package/lib/table/module/menu/panel.min.js +1 -1
  47. package/lib/table/module/validator/mixin.js +271 -259
  48. package/lib/table/module/validator/mixin.min.js +1 -1
  49. package/lib/table/src/body.js +2 -1
  50. package/lib/table/src/body.min.js +1 -1
  51. package/lib/table/src/cell.js +2 -2
  52. package/lib/table/src/cell.min.js +1 -1
  53. package/lib/table/src/methods.js +33 -45
  54. package/lib/table/src/methods.min.js +1 -1
  55. package/lib/table/src/table.js +12 -248
  56. package/lib/table/src/table.min.js +1 -1
  57. package/lib/table/src/util.js +243 -0
  58. package/lib/table/src/util.min.js +1 -1
  59. package/lib/table/style/style.css +23 -50
  60. package/lib/table/style/style.min.css +1 -1
  61. package/lib/ui/index.js +2 -2
  62. package/lib/ui/index.min.js +1 -1
  63. package/lib/ui/src/dom.js +22 -0
  64. package/lib/ui/src/dom.min.js +1 -1
  65. package/lib/ui/src/log.js +1 -1
  66. package/lib/ui/src/log.min.js +1 -1
  67. package/lib/v-x-e-table/index.js +2 -1
  68. package/lib/v-x-e-table/index.min.js +1 -1
  69. package/lib/vxe-colgroup/index.js +2 -1
  70. package/lib/vxe-colgroup/index.min.js +1 -1
  71. package/lib/vxe-column/index.js +2 -1
  72. package/lib/vxe-column/index.min.js +1 -1
  73. package/lib/vxe-grid/index.js +2 -1
  74. package/lib/vxe-grid/index.min.js +1 -1
  75. package/lib/vxe-table/index.js +2 -1
  76. package/lib/vxe-table/index.min.js +1 -1
  77. package/lib/vxe-table/style/style.css +23 -50
  78. package/lib/vxe-table/style/style.min.css +1 -1
  79. package/lib/vxe-toolbar/index.js +2 -1
  80. package/lib/vxe-toolbar/index.min.js +1 -1
  81. package/lib/vxe-ui/index.js +2 -1
  82. package/lib/vxe-ui/index.min.js +1 -1
  83. package/lib/vxe-v-x-e-table/index.js +2 -1
  84. package/lib/vxe-v-x-e-table/index.min.js +1 -1
  85. package/package.json +1 -1
  86. package/packages/table/module/custom/mixin.ts +7 -4
  87. package/packages/table/module/custom/panel.ts +846 -839
  88. package/packages/table/module/edit/mixin.ts +55 -35
  89. package/packages/table/module/export/export-panel.ts +545 -469
  90. package/packages/table/module/export/import-panel.ts +245 -202
  91. package/packages/table/module/filter/panel.ts +4 -18
  92. package/packages/table/module/keyboard/mixin.ts +2 -2
  93. package/packages/table/module/menu/panel.ts +171 -163
  94. package/packages/table/module/validator/mixin.ts +279 -240
  95. package/packages/table/src/body.ts +2 -1
  96. package/packages/table/src/cell.ts +2 -2
  97. package/packages/table/src/methods.ts +43 -45
  98. package/packages/table/src/table.ts +14 -260
  99. package/packages/table/src/util.ts +254 -0
  100. package/packages/ui/index.ts +1 -1
  101. package/packages/ui/src/dom.ts +22 -0
  102. package/styles/components/table.scss +5 -2
  103. package/styles/theme/base.scss +2 -1
  104. /package/es/{iconfont.1767145426781.ttf → iconfont.1767492234857.ttf} +0 -0
  105. /package/es/{iconfont.1767145426781.woff → iconfont.1767492234857.woff} +0 -0
  106. /package/es/{iconfont.1767145426781.woff2 → iconfont.1767492234857.woff2} +0 -0
  107. /package/lib/{iconfont.1767145426781.ttf → iconfont.1767492234857.ttf} +0 -0
  108. /package/lib/{iconfont.1767145426781.woff → iconfont.1767492234857.woff} +0 -0
  109. /package/lib/{iconfont.1767145426781.woff2 → iconfont.1767492234857.woff2} +0 -0
@@ -5,6 +5,7 @@ import { scrollToView } from '../../../ui/src/dom'
5
5
  import { handleFieldOrColumn, getRowid } from '../../src/util'
6
6
  import { warnLog, errLog } from '../../../ui/src/log'
7
7
 
8
+ import type { VxeTooltipInstance } from 'vxe-pc-ui'
8
9
  import type { VxeTableDefines, TableInternalData, TableReactData, VxeTableConstructor, VxeTablePrivateMethods } from '../../../../types'
9
10
 
10
11
  const { getConfig, validators } = VxeUI
@@ -141,240 +142,254 @@ function checkRuleStatus (rule: VxeTableDefines.ValidatorRule, val: any) {
141
142
  return true
142
143
  }
143
144
 
145
+ /**
146
+ * 聚焦到校验通过的单元格并弹出校验错误提示
147
+ */
148
+ function handleValidError ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, params: any) {
149
+ return new Promise<void>(resolve => {
150
+ const validOpts = $xeTable.computeValidOpts
151
+ if (validOpts.autoPos === false) {
152
+ $xeTable.dispatchEvent('valid-error', params, null)
153
+ resolve()
154
+ } else {
155
+ $xeTable.handleEdit(params, { type: 'valid-error', trigger: 'call' }).then(() => {
156
+ setTimeout(() => {
157
+ resolve($xeTable.showValidTooltip(params))
158
+ }, 10)
159
+ })
160
+ }
161
+ })
162
+ }
163
+
164
+ function handleErrMsgMode ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, validErrMaps: any) {
165
+ const validOpts = $xeTable.computeValidOpts
166
+ if (validOpts.msgMode === 'single') {
167
+ const keys = Object.keys(validErrMaps)
168
+ const resMaps: Record<string, {
169
+ row: any;
170
+ column: any;
171
+ rule: any;
172
+ content: any;
173
+ }> = {}
174
+ if (keys.length) {
175
+ const firstKey = keys[0]
176
+ resMaps[firstKey] = validErrMaps[firstKey]
177
+ }
178
+ return resMaps
179
+ }
180
+ return validErrMaps
181
+ }
182
+
183
+ /**
184
+ * 对表格数据进行校验
185
+ * 如果不指定数据,则默认只校验临时变动的数据,例如新增或修改
186
+ * 如果传 true 则校验当前表格数据
187
+ * 如果传 row 指定行记录,则只验证传入的行
188
+ * 如果传 rows 为多行记录,则只验证传入的行
189
+ * 如果只传 callback 否则默认验证整个表格数据
190
+ * 返回 Promise 对象,或者使用回调方式
191
+ */
192
+ function beginValidate ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, rows: any, cols: VxeTableDefines.ColumnInfo[] | null, cb: any, isFull?: boolean) {
193
+ const props = $xeTable
194
+ const reactData = $xeTable as unknown as TableReactData
195
+ const internalData = $xeTable as unknown as TableInternalData
196
+
197
+ const validRest: any = {}
198
+ const { editRules, treeConfig } = props
199
+ const { isRowGroupStatus } = reactData
200
+ const { afterFullData, pendingRowMaps, removeRowMaps } = internalData
201
+ const treeOpts = $xeTable.computeTreeOpts
202
+ const aggregateOpts = $xeTable.computeAggregateOpts
203
+ const validOpts = $xeTable.computeValidOpts
204
+ let validList
205
+ if (rows === true) {
206
+ validList = afterFullData
207
+ } else if (rows) {
208
+ if (XEUtils.isFunction(rows)) {
209
+ cb = rows
210
+ } else {
211
+ validList = XEUtils.isArray(rows) ? rows : [rows]
212
+ }
213
+ }
214
+ if (!validList) {
215
+ validList = $xeTable.getInsertRecords().concat($xeTable.getUpdateRecords())
216
+ }
217
+ const rowValidErrs: any = []
218
+ internalData._lastCallTime = Date.now()
219
+ internalData.validRuleErr = false // 如果为快速校验,当存在某列校验不通过时将终止执行
220
+ $xeTable.clearValidate()
221
+ const validErrMaps: Record<string, {
222
+ row: any;
223
+ column: any;
224
+ rule: any;
225
+ content: any;
226
+ }> = {}
227
+ if (editRules) {
228
+ const columns = cols && cols.length ? cols : $xeTable.getColumns()
229
+ const handleVaild = (row: any) => {
230
+ const rowid = getRowid($xeTable, row)
231
+ // 是否删除
232
+ if (removeRowMaps[rowid]) {
233
+ return
234
+ }
235
+ // 是否标记删除
236
+ if (pendingRowMaps[rowid]) {
237
+ return
238
+ }
239
+ if ($xeTable.isAggregateRecord(row)) {
240
+ return
241
+ }
242
+ if (isFull || !internalData.validRuleErr) {
243
+ const colVailds: any[] = []
244
+ columns.forEach((column: any) => {
245
+ const field = XEUtils.isString(column) ? column : column.field
246
+ if ((isFull || !internalData.validRuleErr) && XEUtils.has(editRules, field)) {
247
+ colVailds.push(
248
+ $xeTable.validCellRules('all', row, column)
249
+ .catch(({ rule, rules }: any) => {
250
+ const rest = {
251
+ rule,
252
+ rules,
253
+ rowIndex: $xeTable.getRowIndex(row),
254
+ row,
255
+ columnIndex: $xeTable.getColumnIndex(column),
256
+ column,
257
+ field,
258
+ $table: $xeTable
259
+ }
260
+ if (!validRest[field]) {
261
+ validRest[field] = []
262
+ }
263
+ validErrMaps[`${getRowid($xeTable, row)}:${column.id}`] = {
264
+ column,
265
+ row,
266
+ rule,
267
+ content: rule.content
268
+ }
269
+ validRest[field].push(rest)
270
+ if (!isFull) {
271
+ internalData.validRuleErr = true
272
+ return Promise.reject(rest)
273
+ }
274
+ })
275
+ )
276
+ }
277
+ })
278
+ rowValidErrs.push(Promise.all(colVailds))
279
+ }
280
+ }
281
+ if (isRowGroupStatus) {
282
+ XEUtils.eachTree(validList, handleVaild, { children: aggregateOpts.mapChildrenField })
283
+ } else if (treeConfig) {
284
+ const childrenField = treeOpts.children || treeOpts.childrenField
285
+ XEUtils.eachTree(validList, handleVaild, { children: childrenField })
286
+ } else {
287
+ validList.forEach(handleVaild)
288
+ }
289
+ return Promise.all(rowValidErrs).then(() => {
290
+ const ruleProps = Object.keys(validRest)
291
+ reactData.validErrorMaps = handleErrMsgMode($xeTable, validErrMaps)
292
+ return $xeTable.$nextTick().then(() => {
293
+ if (ruleProps.length) {
294
+ return Promise.reject(validRest[ruleProps[0]][0])
295
+ }
296
+ if (cb) {
297
+ cb()
298
+ }
299
+ })
300
+ }).catch(firstErrParams => {
301
+ return new Promise<void>((resolve, reject) => {
302
+ const finish = () => {
303
+ $xeTable.$nextTick(() => {
304
+ if (cb) {
305
+ cb(validRest)
306
+ resolve()
307
+ } else {
308
+ if (getConfig().validToReject === 'obsolete') {
309
+ // 已废弃,校验失败将不会执行catch
310
+ reject(validRest)
311
+ } else {
312
+ resolve(validRest)
313
+ }
314
+ }
315
+ })
316
+ }
317
+ const posAndFinish = () => {
318
+ firstErrParams.cell = $xeTable.getCellElement(firstErrParams.row, firstErrParams.column)
319
+ scrollToView(firstErrParams.cell)
320
+ handleValidError($xeTable, firstErrParams).then(finish)
321
+ }
322
+ /**
323
+ * 当校验不通过时
324
+ * 将表格滚动到可视区
325
+ * 由于提示信息至少需要占一行,定位向上偏移一行
326
+ */
327
+ if (validOpts.autoPos === false) {
328
+ finish()
329
+ } else {
330
+ const row = firstErrParams.row
331
+ const column = firstErrParams.column
332
+ $xeTable.scrollToRow(row, column).then(posAndFinish)
333
+ }
334
+ })
335
+ })
336
+ } else {
337
+ reactData.validErrorMaps = {}
338
+ }
339
+ return $xeTable.$nextTick().then(() => {
340
+ if (cb) {
341
+ cb()
342
+ }
343
+ })
344
+ }
345
+
144
346
  export default {
145
347
  methods: {
146
348
  /**
147
349
  * 完整校验,和 validate 的区别就是会给有效数据中的每一行进行校验
148
350
  */
149
351
  _fullValidate (rows: any, cb: any) {
352
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
353
+
150
354
  if (XEUtils.isFunction(cb)) {
151
355
  warnLog('vxe.error.notValidators', ['fullValidate(rows, callback)', 'fullValidate(rows)'])
152
356
  }
153
- return this.beginValidate(rows, null, cb, true)
357
+ return beginValidate($xeTable, rows, null, cb, true)
154
358
  },
155
359
  /**
156
360
  * 快速校验,如果存在记录不通过的记录,则返回不再继续校验(异步校验除外)
157
361
  */
158
362
  _validate (rows: any, cb: any) {
363
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
364
+
159
365
  if (XEUtils.isFunction(cb)) {
160
366
  warnLog('vxe.error.notValidators', ['validate(rows, callback)', 'validate(rows)'])
161
367
  }
162
- return this.beginValidate(rows, null, cb)
368
+ return beginValidate($xeTable, rows, null, cb)
163
369
  },
164
370
  /**
165
371
  * 完整校验单元格,和 validateField 的区别就是会给有效数据中的每一行进行校验
166
372
  */
167
373
  _fullValidateField (rows: any, fieldOrColumn: any) {
374
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
375
+
168
376
  const colList = (XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : (fieldOrColumn ? [fieldOrColumn] : [])).map(column => handleFieldOrColumn(this, column))
169
377
  if (colList.length) {
170
- return this.beginValidate(rows, colList, null, true)
378
+ return beginValidate($xeTable, rows, colList, null, true)
171
379
  }
172
- return this.$nextTick()
380
+ return $xeTable.$nextTick()
173
381
  },
174
382
  /**
175
383
  * 快速校验单元格,如果存在记录不通过的记录,则返回不再继续校验(异步校验除外)
176
384
  */
177
385
  _validateField (rows: any, fieldOrColumn: any) {
178
- const colList = (XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : (fieldOrColumn ? [fieldOrColumn] : [])).map(column => handleFieldOrColumn(this, column))
179
- if (colList.length) {
180
- return this.beginValidate(rows, colList, null)
181
- }
182
- return this.$nextTick()
183
- },
184
- /**
185
- * 聚焦到校验通过的单元格并弹出校验错误提示
186
- */
187
- handleValidError (params: any) {
188
- const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
189
-
190
- const { validOpts } = this
191
- return new Promise<void>(resolve => {
192
- if (validOpts.autoPos === false) {
193
- $xeTable.dispatchEvent('valid-error', params, null)
194
- resolve()
195
- } else {
196
- this.handleEdit(params, { type: 'valid-error', trigger: 'call' }).then(() => {
197
- setTimeout(() => {
198
- resolve(this.showValidTooltip(params))
199
- }, 10)
200
- })
201
- }
202
- })
203
- },
204
- handleErrMsgMode (validErrMaps: any) {
205
- const { validOpts } = this
206
- if (validOpts.msgMode === 'single') {
207
- const keys = Object.keys(validErrMaps)
208
- const resMaps: Record<string, {
209
- row: any;
210
- column: any;
211
- rule: any;
212
- content: any;
213
- }> = {}
214
- if (keys.length) {
215
- const firstKey = keys[0]
216
- resMaps[firstKey] = validErrMaps[firstKey]
217
- }
218
- return resMaps
219
- }
220
- return validErrMaps
221
- },
222
- /**
223
- * 对表格数据进行校验
224
- * 如果不指定数据,则默认只校验临时变动的数据,例如新增或修改
225
- * 如果传 true 则校验当前表格数据
226
- * 如果传 row 指定行记录,则只验证传入的行
227
- * 如果传 rows 为多行记录,则只验证传入的行
228
- * 如果只传 callback 否则默认验证整个表格数据
229
- * 返回 Promise 对象,或者使用回调方式
230
- */
231
- beginValidate (rows: any, cols: VxeTableDefines.ColumnInfo[] | null, cb: any, isFull: any) {
232
386
  const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
233
- const props = $xeTable
234
- const reactData = $xeTable as unknown as TableReactData
235
- const internalData = $xeTable as unknown as TableInternalData
236
387
 
237
- const validRest: any = {}
238
- const { editRules, treeConfig } = props
239
- const { isRowGroupStatus } = reactData
240
- const { afterFullData, pendingRowMaps, removeRowMaps } = internalData
241
- const treeOpts = $xeTable.computeTreeOpts
242
- const aggregateOpts = $xeTable.computeAggregateOpts
243
- let validList
244
- if (rows === true) {
245
- validList = afterFullData
246
- } else if (rows) {
247
- if (XEUtils.isFunction(rows)) {
248
- cb = rows
249
- } else {
250
- validList = XEUtils.isArray(rows) ? rows : [rows]
251
- }
252
- }
253
- if (!validList) {
254
- validList = this.getInsertRecords().concat(this.getUpdateRecords())
255
- }
256
- const rowValidErrs: any[] = []
257
- this.lastCallTime = Date.now()
258
- this.validRuleErr = false // 如果为快速校验,当存在某列校验不通过时将终止执行
259
- this.clearValidate()
260
- const validErrMaps: any = {}
261
- if (editRules) {
262
- const columns = cols && cols.length ? cols : this.getColumns()
263
- const handleVaild = (row: any) => {
264
- const rowid = getRowid($xeTable, row)
265
- // 是否删除
266
- if (removeRowMaps[rowid]) {
267
- return
268
- }
269
- // 是否标记删除
270
- if (pendingRowMaps[rowid]) {
271
- return
272
- }
273
- if ($xeTable.isAggregateRecord(row)) {
274
- return
275
- }
276
- if (isFull || !this.validRuleErr) {
277
- const colVailds: any[] = []
278
- columns.forEach((column: any) => {
279
- const field = XEUtils.isString(column) ? column : column.field
280
- if ((isFull || !this.validRuleErr) && XEUtils.has(editRules, field)) {
281
- colVailds.push(
282
- this.validCellRules('all', row, column)
283
- .catch(({ rule, rules }: any) => {
284
- const rest = {
285
- rule,
286
- rules,
287
- rowIndex: this.getRowIndex(row),
288
- row,
289
- columnIndex: this.getColumnIndex(column),
290
- column,
291
- field,
292
- $table: this
293
- }
294
- if (!validRest[field]) {
295
- validRest[field] = []
296
- }
297
- validErrMaps[`${getRowid(this, row)}:${column.id}`] = {
298
- column,
299
- row,
300
- rule,
301
- content: rule.content
302
- }
303
- validRest[field].push(rest)
304
- if (!isFull) {
305
- this.validRuleErr = true
306
- return Promise.reject(rest)
307
- }
308
- })
309
- )
310
- }
311
- })
312
- rowValidErrs.push(Promise.all(colVailds))
313
- }
314
- }
315
- if (isRowGroupStatus) {
316
- XEUtils.eachTree(validList, handleVaild, { children: aggregateOpts.mapChildrenField })
317
- } else if (treeConfig) {
318
- const childrenField = treeOpts.children || treeOpts.childrenField
319
- XEUtils.eachTree(validList, handleVaild, { children: childrenField })
320
- } else {
321
- validList.forEach(handleVaild)
322
- }
323
- return Promise.all(rowValidErrs).then(() => {
324
- const ruleProps = Object.keys(validRest)
325
- this.validErrorMaps = this.handleErrMsgMode(validErrMaps)
326
- return this.$nextTick().then(() => {
327
- if (ruleProps.length) {
328
- return Promise.reject(validRest[ruleProps[0]][0])
329
- }
330
- if (cb) {
331
- cb()
332
- }
333
- })
334
- }).catch(firstErrParams => {
335
- return new Promise<void>((resolve, reject) => {
336
- const finish = () => {
337
- this.$nextTick(() => {
338
- if (cb) {
339
- cb(validRest)
340
- resolve()
341
- } else {
342
- if (getConfig().validToReject === 'obsolete') {
343
- // 已废弃,校验失败将不会执行catch
344
- reject(validRest)
345
- } else {
346
- resolve(validRest)
347
- }
348
- }
349
- })
350
- }
351
- const posAndFinish = () => {
352
- firstErrParams.cell = this.getCellElement(firstErrParams.row, firstErrParams.column)
353
- scrollToView(firstErrParams.cell)
354
- this.handleValidError(firstErrParams).then(finish)
355
- }
356
- /**
357
- * 当校验不通过时
358
- * 将表格滚动到可视区
359
- * 由于提示信息至少需要占一行,定位向上偏移一行
360
- */
361
- if (this.validOpts.autoPos === false) {
362
- finish()
363
- } else {
364
- const row = firstErrParams.row
365
- const column = firstErrParams.column
366
- this.scrollToRow(row, column).then(posAndFinish)
367
- }
368
- })
369
- })
370
- } else {
371
- this.validErrorMaps = {}
388
+ const colList = (XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : (fieldOrColumn ? [fieldOrColumn] : [])).map(column => handleFieldOrColumn(this, column))
389
+ if (colList.length) {
390
+ return beginValidate($xeTable, rows, colList, null)
372
391
  }
373
- return this.$nextTick().then(() => {
374
- if (cb) {
375
- cb()
376
- }
377
- })
392
+ return $xeTable.$nextTick()
378
393
  },
379
394
  hasCellRules (type: any, row: any, column: any) {
380
395
  const { editRules } = this
@@ -400,14 +415,18 @@ export default {
400
415
  * trigger=blur|change 触发方式(除非特殊场景,否则默认为空就行)
401
416
  */
402
417
  validCellRules (validType: any, row: any, column: any, val: any) {
403
- const { editRules } = this
404
- const { property } = column
405
- const errorRules: any[] = []
406
- const syncValidList: any[] = []
407
- if (property && editRules) {
408
- const rules = XEUtils.get(editRules, property)
418
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
419
+ const props = $xeTable
420
+ const internalData = $xeTable as unknown as TableInternalData
421
+
422
+ const { editRules } = props
423
+ const { field } = column
424
+ const errorRules: Rule[] = []
425
+ const syncValidList: Promise<any>[] = []
426
+ if (field && editRules) {
427
+ const rules = XEUtils.get(editRules, field)
409
428
  if (rules) {
410
- const cellValue = XEUtils.isUndefined(val) ? XEUtils.get(row, property) : val
429
+ const cellValue = XEUtils.isUndefined(val) ? XEUtils.get(row, field) : val
411
430
  rules.forEach((rule: any) => {
412
431
  const { trigger, validator } = rule
413
432
  if (validType === 'all' || !trigger || validType === trigger) {
@@ -417,11 +436,11 @@ export default {
417
436
  rule,
418
437
  rules,
419
438
  row,
420
- rowIndex: this.getRowIndex(row),
439
+ rowIndex: $xeTable.getRowIndex(row),
421
440
  column,
422
- columnIndex: this.getColumnIndex(column),
423
- field: column.property,
424
- $table: this
441
+ columnIndex: $xeTable.getColumnIndex(column),
442
+ field: column.field,
443
+ $table: $xeTable
425
444
  }
426
445
  let customValid
427
446
  if (XEUtils.isString(validator)) {
@@ -441,13 +460,13 @@ export default {
441
460
  }
442
461
  if (customValid) {
443
462
  if (XEUtils.isError(customValid)) {
444
- this.validRuleErr = true
463
+ internalData.validRuleErr = true
445
464
  errorRules.push(new Rule({ type: 'custom', trigger, content: customValid.message, rule: new Rule(rule) }))
446
465
  } else if (customValid.catch) {
447
466
  // 如果为异步校验(注:异步校验是并发无序的)
448
467
  syncValidList.push(
449
468
  customValid.catch((e: any) => {
450
- this.validRuleErr = true
469
+ internalData.validRuleErr = true
451
470
  errorRules.push(new Rule({ type: 'custom', trigger, content: e && e.message ? e.message : (rule.content || rule.message), rule: new Rule(rule) }))
452
471
  })
453
472
  )
@@ -455,7 +474,7 @@ export default {
455
474
  }
456
475
  } else {
457
476
  if (!checkRuleStatus(rule, cellValue)) {
458
- this.validRuleErr = true
477
+ internalData.validRuleErr = true
459
478
  errorRules.push(new Rule(rule))
460
479
  }
461
480
  }
@@ -470,32 +489,41 @@ export default {
470
489
  }
471
490
  })
472
491
  },
473
- _clearValidate (rows: any, fieldOrColumn: any) {
474
- const { validOpts, validErrorMaps } = this
475
- const validTip = this.$refs.refValidTooltip
492
+ _clearValidate (rows: any, fieldOrColumn: any) {
493
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
494
+ const reactData = $xeTable as unknown as TableReactData
495
+
496
+ const { validErrorMaps } = reactData
497
+ const validTip = $xeTable.$refs.refValidTooltip as VxeTooltipInstance
498
+ const validOpts = $xeTable.computeValidOpts
476
499
  const rowList = XEUtils.isArray(rows) ? rows : (rows ? [rows] : [])
477
- const colList = (XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : (fieldOrColumn ? [fieldOrColumn] : [])).map(column => handleFieldOrColumn(this, column))
478
- let validErrMaps: any = {}
479
- if (validTip && validTip.visible) {
500
+ const colList = (XEUtils.isArray(fieldOrColumn) ? fieldOrColumn : (fieldOrColumn ? [fieldOrColumn] : [])).map(column => handleFieldOrColumn($xeTable, column)) as VxeTableDefines.ColumnInfo<any>[]
501
+ let validErrMaps: Record<string, {
502
+ row: any;
503
+ column: any;
504
+ rule: any;
505
+ content: any;
506
+ }> = {}
507
+ if (validTip && validTip.reactData.visible) {
480
508
  validTip.close()
481
509
  }
482
510
  // 如果是单个提示模式
483
511
  if (validOpts.msgMode === 'single') {
484
- this.validErrorMaps = {}
485
- return this.$nextTick()
512
+ reactData.validErrorMaps = {}
513
+ return $xeTable.$nextTick()
486
514
  }
487
515
  if (rowList.length && colList.length) {
488
516
  validErrMaps = Object.assign({}, validErrorMaps)
489
517
  rowList.forEach(row => {
490
518
  colList.forEach((column) => {
491
- const validKey = `${getRowid(this, row)}:${column.id}`
519
+ const validKey = `${getRowid($xeTable, row)}:${column.id}`
492
520
  if (validErrMaps[validKey]) {
493
521
  delete validErrMaps[validKey]
494
522
  }
495
523
  })
496
524
  })
497
525
  } else if (rowList.length) {
498
- const rowIdList = rowList.map(row => `${getRowid(this, row)}`)
526
+ const rowIdList = rowList.map(row => `${getRowid($xeTable, row)}`)
499
527
  XEUtils.each(validErrorMaps, (item, key) => {
500
528
  if (rowIdList.indexOf(key.split(':')[0]) > -1) {
501
529
  validErrMaps[key] = item
@@ -509,33 +537,40 @@ export default {
509
537
  }
510
538
  })
511
539
  }
512
- this.validErrorMaps = validErrMaps
513
- return this.$nextTick()
540
+ reactData.validErrorMaps = validErrMaps
541
+ return $xeTable.$nextTick()
514
542
  },
515
543
  /**
516
544
  * 触发校验
517
545
  */
518
546
  triggerValidate (type: any) {
519
- const { editConfig, editStore, editRules, editOpts, validOpts } = this
547
+ const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
548
+ const props = $xeTable
549
+ const reactData = $xeTable as unknown as TableReactData
550
+
551
+ const { editConfig, editRules } = props
552
+ const { editStore } = reactData
520
553
  const { actived } = editStore
554
+ const editOpts = $xeTable.computeEditOpts
555
+ const validOpts = $xeTable.computeValidOpts
521
556
  // 检查清除校验消息
522
557
  if (editRules && validOpts.msgMode === 'single') {
523
- this.validErrorMaps = {}
558
+ reactData.validErrorMaps = {}
524
559
  }
525
560
 
526
561
  // 校验单元格
527
562
  if (editConfig && editRules && actived.row) {
528
563
  const { row, column, cell } = actived.args
529
- if (this.hasCellRules(type, row, column)) {
530
- return this.validCellRules(type, row, column).then(() => {
564
+ if ($xeTable.hasCellRules(type, row, column)) {
565
+ return $xeTable.validCellRules(type, row, column).then(() => {
531
566
  if (editOpts.mode === 'row') {
532
- this.clearValidate(row, column)
567
+ $xeTable.clearValidate(row, column)
533
568
  }
534
569
  }).catch(({ rule }: any) => {
535
570
  // 如果校验不通过与触发方式一致,则聚焦提示错误,否则跳过并不作任何处理
536
571
  if (!rule.trigger || type === rule.trigger) {
537
572
  const rest = { rule, row, column, cell }
538
- this.showValidTooltip(rest)
573
+ $xeTable.showValidTooltip(rest)
539
574
  return Promise.reject(rest)
540
575
  }
541
576
  return Promise.resolve()
@@ -549,15 +584,19 @@ export default {
549
584
  */
550
585
  showValidTooltip (params: any) {
551
586
  const $xeTable = this as VxeTableConstructor & VxeTablePrivateMethods
587
+ const props = $xeTable
588
+ const reactData = $xeTable as unknown as TableReactData
552
589
 
553
- const { $refs, height, validStore, validErrorMaps, tableData, validOpts } = this
590
+ const { height } = props
591
+ const { tableData, validStore, validErrorMaps } = reactData
554
592
  const { rule, row, column, cell } = params
555
- const validTip = $refs.refValidTooltip
593
+ const validOpts = $xeTable.computeValidOpts
594
+ const validTip = $xeTable.$refs.refValidTooltip as VxeTooltipInstance
556
595
  const content = rule.content
557
596
  validStore.visible = true
558
597
  if (validOpts.msgMode === 'single') {
559
- this.validErrorMaps = {
560
- [`${getRowid(this, row)}:${column.id}`]: {
598
+ reactData.validErrorMaps = {
599
+ [`${getRowid($xeTable, row)}:${column.id}`]: {
561
600
  column,
562
601
  row,
563
602
  rule,
@@ -565,8 +604,8 @@ export default {
565
604
  }
566
605
  }
567
606
  } else {
568
- this.validErrorMaps = Object.assign({}, validErrorMaps, {
569
- [`${getRowid(this, row)}:${column.id}`]: {
607
+ reactData.validErrorMaps = Object.assign({}, validErrorMaps, {
608
+ [`${getRowid($xeTable, row)}:${column.id}`]: {
570
609
  column,
571
610
  row,
572
611
  rule,
@@ -580,7 +619,7 @@ export default {
580
619
  return validTip.open(cell, content)
581
620
  }
582
621
  }
583
- return this.$nextTick()
622
+ return $xeTable.$nextTick()
584
623
  }
585
624
  } as any
586
625
  }
@@ -155,7 +155,7 @@ function renderTdColumn (
155
155
  const cellAlign = align || (compConf ? compConf.tableCellAlign : '') || allAlign
156
156
  const cellVerticalAlign = XEUtils.eqNull(verticalAlign) ? allVerticalAlign : verticalAlign
157
157
  const errorValidItem = validErrorMaps[`${rowid}:${colid}`]
158
- const showValidTip = editRules && validOpts.showMessage && (validOpts.message === 'default' ? (height || tableData.length > 1) : validOpts.message === 'inline')
158
+ const showValidTip = editRules && validOpts.showErrorMessage && (validOpts.message === 'default' ? (height || tableData.length > 1) : validOpts.message === 'inline')
159
159
  const tdAttrs: any = { colid }
160
160
  const cellParams: VxeTableDefines.CellRenderBodyParams & {
161
161
  $table: VxeTableConstructor<any> & VxeTablePrivateMethods
@@ -460,6 +460,7 @@ function renderTdColumn (
460
460
  'col--dirty': isDirty,
461
461
  'col--active': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
462
462
  'col--valid-error': !!errorValidItem,
463
+ 'show--valid-bg': errorValidItem && validOpts.showErrorBackground,
463
464
  'col--current': currentColumn === column
464
465
  },
465
466
  getClass(compCellClassName, cellParams),