element-ui-pro-components-test 1.5.0

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 (53) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/LICENSE +21 -0
  3. package/README.md +0 -0
  4. package/lib/dialog-form.js +1175 -0
  5. package/lib/editable-pro-table.js +2080 -0
  6. package/lib/element-ui-pro-components.common.js +193 -0
  7. package/lib/index.js +1 -0
  8. package/lib/locale/index.js +44 -0
  9. package/lib/locale/lang/en.js +46 -0
  10. package/lib/locale/lang/zh-CN.js +46 -0
  11. package/lib/pro-form.js +1036 -0
  12. package/lib/pro-table.js +2779 -0
  13. package/lib/theme-chalk/editable-pro-table.css +1 -0
  14. package/lib/theme-chalk/index.css +1 -0
  15. package/lib/theme-chalk/pro-table.css +1 -0
  16. package/lib/umd/locale/en.js +67 -0
  17. package/lib/umd/locale/zh-CN.js +67 -0
  18. package/lib/utils/breakpoints.js +68 -0
  19. package/lib/utils/debounce.js +20 -0
  20. package/lib/utils/form.js +108 -0
  21. package/package.json +78 -0
  22. package/packages/dialog-form/index.js +9 -0
  23. package/packages/dialog-form/src/components/Submitter.vue +47 -0
  24. package/packages/dialog-form/src/index.vue +404 -0
  25. package/packages/editable-pro-table/index.js +9 -0
  26. package/packages/editable-pro-table/src/components/Editable.vue +203 -0
  27. package/packages/editable-pro-table/src/components/FormItem.vue +193 -0
  28. package/packages/editable-pro-table/src/components/RecordCreator.vue +43 -0
  29. package/packages/editable-pro-table/src/components/RenderCell.vue +181 -0
  30. package/packages/editable-pro-table/src/index.vue +805 -0
  31. package/packages/pro-form/index.js +9 -0
  32. package/packages/pro-form/src/components/Submitter.vue +47 -0
  33. package/packages/pro-form/src/index.vue +309 -0
  34. package/packages/pro-table/index.js +9 -0
  35. package/packages/pro-table/src/components/ColumnAlignSettings.vue +77 -0
  36. package/packages/pro-table/src/components/ColumnSettings.vue +172 -0
  37. package/packages/pro-table/src/components/ColumnSettingsItem.vue +401 -0
  38. package/packages/pro-table/src/components/svg/ArrowIcon.vue +16 -0
  39. package/packages/pro-table/src/components/svg/HolderIcon.vue +17 -0
  40. package/packages/pro-table/src/components/svg/SettingIcon.vue +20 -0
  41. package/packages/pro-table/src/components/svg/VerticalAlginBottomIcon.vue +17 -0
  42. package/packages/pro-table/src/components/svg/VerticalAlginMiddleIcon.vue +17 -0
  43. package/packages/pro-table/src/components/svg/VerticalAlignTopIcon.vue +17 -0
  44. package/packages/pro-table/src/index.vue +934 -0
  45. package/src/components/custom-render/index.vue +16 -0
  46. package/src/components/pro-form-item/index.vue +129 -0
  47. package/src/index.js +57 -0
  48. package/src/locale/index.js +47 -0
  49. package/src/locale/lang/en.js +46 -0
  50. package/src/locale/lang/zh-CN.js +46 -0
  51. package/src/utils/breakpoints.js +61 -0
  52. package/src/utils/debounce.js +22 -0
  53. package/src/utils/form.js +94 -0
@@ -0,0 +1,805 @@
1
+ <template>
2
+ <component
3
+ :is="formRef ? 'fragment' : 'el-form'"
4
+ v-bind="getDynamicProps"
5
+ >
6
+ <el-table-prepend
7
+ ref="editableProTableRef"
8
+ class="editable-pro-table"
9
+ :class="className"
10
+ v-loading="loading"
11
+ :data="form[name]"
12
+ v-bind="initializedTableProps"
13
+ v-on="tableEvents"
14
+ >
15
+ <template v-if="initializedCreatorProps.position === 'top' && !exceedsMax" #prepend>
16
+ <div class="btn-add-box">
17
+ <RecordCreator
18
+ :recordCreatorProps="initializedCreatorProps"
19
+ :size="defaultSize"
20
+ @click.native="addEditRecord(null)"
21
+ />
22
+ </div>
23
+ </template>
24
+ <el-table-column
25
+ v-for="(column, index) in initializedColumns"
26
+ v-bind="getColumnProps(column, index)"
27
+ :key="column.prop || column.key || `${column.type}-col`"
28
+ >
29
+ <template v-if="column.renderCellHeader" #header="scope">
30
+ <!-- 覆写头部 -->
31
+ <!-- start -->
32
+ <CustomRender :render="() => column.renderCellHeader(scope)" />
33
+ <!-- end -->
34
+ </template>
35
+ <template v-if="column.valueType || column.renderField" #default="scope">
36
+ <template v-if="column.valueType === 'option'">
37
+ <!-- 操作栏 -->
38
+ <!-- start -->
39
+ <Editable
40
+ :editable="initializedEditable"
41
+ :actions="{
42
+ cancelEditable,
43
+ startEditable,
44
+ addEditRecord
45
+ }"
46
+ :validateRow="validateRow"
47
+ :recordKey="scope.row[rowKey]"
48
+ :scope="scope"
49
+ :name="name"
50
+ :render="(actions) => column.renderCell(scope, actions)"
51
+ :newLineRecordCache="newLineRecordCache"
52
+ :preEditRows="preEditRows"
53
+ :defaultSize="defaultSize"
54
+ @delete="filterByRecordKey"
55
+ @cancel="deleteOrResetRow"
56
+ />
57
+ <!-- end -->
58
+ </template>
59
+ <template v-else>
60
+ <RenderCell
61
+ :editable="initializedEditable"
62
+ :column="column"
63
+ :name="name"
64
+ :recordKey="scope.row[rowKey]"
65
+ :scope="scope"
66
+ :cachedOptions="cachedOptions"
67
+ :preEditRows="preEditRows"
68
+ >
69
+ <template #[column.prop]="scope">
70
+ <slot :name="column.prop" v-bind="scope"></slot>
71
+ </template>
72
+ </RenderCell>
73
+ </template>
74
+ </template>
75
+ </el-table-column>
76
+ </el-table-prepend>
77
+ <RecordCreator
78
+ v-if="initializedCreatorProps.position === 'bottom' && !exceedsMax"
79
+ :recordCreatorProps="initializedCreatorProps"
80
+ :size="defaultSize"
81
+ @click.native="addEditRecord(null)"
82
+ />
83
+ </component>
84
+ </template>
85
+
86
+ <script>
87
+ import ElTablePrepend from 'el-table-prepend'
88
+ import RecordCreator from './components/RecordCreator'
89
+ import CustomRender from '@/components/custom-render'
90
+ import RenderCell from './components/RenderCell'
91
+ import Editable from './components/Editable'
92
+ import { t } from 'element-ui-pro-components/src/locale'
93
+
94
+ export default {
95
+ name: 'EditableProTable',
96
+ components: {
97
+ ElTablePrepend,
98
+ RecordCreator,
99
+ CustomRender,
100
+ RenderCell,
101
+ Editable
102
+ },
103
+ // 组件外 el-form 的引用
104
+ inject: {
105
+ formRef: {
106
+ from: 'elForm',
107
+ default: null
108
+ }
109
+ },
110
+ props: {
111
+ // el-table 的数据
112
+ dataSource: {
113
+ type: Array,
114
+ required: true,
115
+ default: () => []
116
+ },
117
+ // 新建一行数据的相关配置
118
+ recordCreatorProps: {
119
+ type: [Boolean, Object],
120
+ default: true
121
+ },
122
+ // 最大的行数
123
+ maxLength: {
124
+ type: Number,
125
+ },
126
+ // 可编辑表格的相关配置
127
+ editable: {
128
+ type: Object,
129
+ },
130
+ // 行数据的 Key
131
+ rowKey: {
132
+ type: String
133
+ },
134
+ // 表格名称
135
+ name: {
136
+ type: String,
137
+ default: 'dataSource'
138
+ },
139
+ // el-table 的类名
140
+ className: {
141
+ type: String
142
+ },
143
+ // 加载中
144
+ loading: {
145
+ type: Boolean,
146
+ },
147
+ // el-table attributes 的配置
148
+ tableProps: {
149
+ type: Object
150
+ },
151
+ // el-table events 的配置
152
+ tableEvents: {
153
+ type: Object,
154
+ },
155
+ // 列定义
156
+ columns: {
157
+ type: Array,
158
+ required: true,
159
+ default: () => []
160
+ },
161
+ // 默认的 size
162
+ defaultSize: {
163
+ type: String,
164
+ validator: function (value) {
165
+ return ['medium', 'small', 'mini'].includes(value)
166
+ },
167
+ },
168
+ // 固定列是否使用 position: sticky 实现
169
+ sticky: {
170
+ type: Boolean,
171
+ default: true
172
+ }
173
+ },
174
+ computed: {
175
+ getDynamicProps() {
176
+ const { formRef, form, defaultSize } = this
177
+
178
+ if (!formRef) {
179
+ return {
180
+ ref: 'formRef',
181
+ model: form,
182
+ size: defaultSize
183
+ }
184
+ }
185
+
186
+ return
187
+ },
188
+ // recordCreatorProps 初始化
189
+ initializedCreatorProps() {
190
+ const { recordCreatorProps } = this
191
+ if (recordCreatorProps) {
192
+ const defaultRecordCreatorProps = {
193
+ position: 'bottom',
194
+ newRecordType: 'cache',
195
+ creatorButtonText: t('elProComponents.editableProTable.add'),
196
+ onlyAddOneLineAlertMessage: t('elProComponents.editableProTable.onlyAddOneLine')
197
+ }
198
+ if (typeof recordCreatorProps === 'object') {
199
+ return {
200
+ ...defaultRecordCreatorProps,
201
+ ...recordCreatorProps
202
+ }
203
+ }
204
+
205
+ return defaultRecordCreatorProps
206
+ }
207
+
208
+ return false
209
+ },
210
+ // 是否超过了最大的行数
211
+ exceedsMax() {
212
+ const { maxLength } = this
213
+ if (typeof maxLength === 'number') {
214
+ return this.form[this.name].length >= maxLength
215
+ }
216
+
217
+ return false
218
+ },
219
+ // editable 初始化
220
+ initializedEditable() {
221
+ const defaultEditable = {
222
+ type: 'single',
223
+ saveText: t('elProComponents.editableProTable.save'),
224
+ deleteText: t('elProComponents.editableProTable.delete'),
225
+ cancelText: t('elProComponents.editableProTable.cancel'),
226
+ deletePopconfirmMessage: t('elProComponents.editableProTable.deleteThisLine'),
227
+ onlyOneLineEditorAlertMessage: t('elProComponents.editableProTable.onlyOneLineEditor'),
228
+ }
229
+
230
+ return {
231
+ ...defaultEditable,
232
+ ...this.editable
233
+ }
234
+ },
235
+ // tableProps 初始化
236
+ initializedTableProps() {
237
+ const { rowKey, tableProps = {}, defaultSize: size } = this
238
+ return {
239
+ ...tableProps,
240
+ rowKey,
241
+ size,
242
+ 'cell-style': (data) => this.getCellStyle(data, tableProps['cell-style']),
243
+ 'header-cell-style': (data) => this.getCellStyle(data, tableProps['header-cell-style']),
244
+ }
245
+ },
246
+ // columns 初始化
247
+ initializedColumns() {
248
+ return this.columns.filter(item => !item.hideInTable)
249
+ },
250
+ // 计算定位的偏移
251
+ calculateOffset() {
252
+ const offset = {}
253
+ const { initializedColumns, sticky } = this
254
+ let totalLeftOffset = 0
255
+ let leftIndex = -1
256
+ for (let i = 0; i < initializedColumns.length; i++) {
257
+ const col = initializedColumns[i]
258
+ const isSticky = sticky !== false && col.fixed === 'left'
259
+ if (isSticky) {
260
+ leftIndex = i
261
+ offset[i] = totalLeftOffset
262
+ totalLeftOffset += col.width || col.minWidth
263
+ }
264
+ }
265
+
266
+ let totalRightOffset = 0
267
+ let rightIndex = -1
268
+ for (let i = initializedColumns.length - 1; i >= 0; i--) {
269
+ const col = initializedColumns[i]
270
+ const isSticky = sticky !== false && col.fixed === 'right'
271
+ if (isSticky) {
272
+ rightIndex = i
273
+ offset[i] = totalRightOffset
274
+ totalRightOffset += col.width || col.minWidth
275
+ }
276
+ }
277
+
278
+ return {
279
+ offset,
280
+ leftIndex,
281
+ rightIndex
282
+ }
283
+ },
284
+ },
285
+ data() {
286
+ return {
287
+ cachedOptions: {}, // 下拉数据 { [prop]: data }
288
+ form: {
289
+ [this.name]: this.dataSource
290
+ },
291
+ newLineRecordCache: undefined, // 新增一行草稿数据
292
+ preEditRows: new Map(), // 编辑前行数据
293
+ }
294
+ },
295
+ created () {
296
+ // 获取异步数据
297
+ this.getOptions()
298
+ },
299
+ watch: {
300
+ // 监听元数据变化
301
+ dataSource(newValue) {
302
+ this.form[this.name] = newValue
303
+ },
304
+ },
305
+ methods: {
306
+ /**
307
+ * @desc 获取异步下拉数据
308
+ */
309
+ getOptions() {
310
+ for (const item of this.columns) {
311
+ const { prop, optionLoader } = item
312
+ if (typeof optionLoader === 'function') {
313
+ optionLoader().then(res => {
314
+ this.cachedOptions = {
315
+ ...this.cachedOptions,
316
+ [prop]: res
317
+ }
318
+ })
319
+ }
320
+ }
321
+ },
322
+ /**
323
+ * @desc 初始化表单字段
324
+ */
325
+ getInitialValues() {
326
+ return this.initializedColumns
327
+ .reduce((accu, cur) => {
328
+ const { prop } = cur
329
+ if (!prop) {
330
+ return accu
331
+ }
332
+
333
+ return {
334
+ ...accu,
335
+ [prop]: undefined
336
+ }
337
+ }, {})
338
+ },
339
+ /**
340
+ * 新增一行的方法
341
+ * @param record 数据
342
+ * @param newLine 新增一行的配置
343
+ */
344
+ addEditRecord(record, newLine) {
345
+ const { initializedCreatorProps: { onlyAddOneLineAlertMessage } } = this
346
+ // 只能新增一行校验
347
+ if (this.newLineRecordCache) {
348
+ this.$message.warning(onlyAddOneLineAlertMessage)
349
+ return
350
+ }
351
+
352
+ // 只能同时编辑一行校验
353
+ if (!this.validateCanStartEdit()) {
354
+ return
355
+ }
356
+
357
+ const { form, name, rowKey } = this
358
+ const { initializedCreatorProps: { position, newRecordType, record: defaultRecord } } = this
359
+ const dataSource = form[name]
360
+ const newLineConfig = {
361
+ position,
362
+ newRecordType,
363
+ ...(newLine || {})
364
+ }
365
+ const index = newLineConfig.position === 'top' ? dataSource.length : 0
366
+ record = record ?? defaultRecord
367
+ const newRecord = {
368
+ ...this.getInitialValues(),
369
+ ...(typeof record === 'function' ? record(index, dataSource) : record)
370
+ }
371
+ if (!newRecord[rowKey]) {
372
+ console.error('Error: 请设置 recordCreatorProps.record 并返回一个唯一的key')
373
+ return
374
+ }
375
+
376
+ // 记录缓存数据
377
+ if (newLineConfig.newRecordType !== 'dataSource') {
378
+ this.newLineRecordCache = {
379
+ // 深拷贝防止引用
380
+ defaultValue: JSON.parse(JSON.stringify(newRecord)),
381
+ options: {
382
+ ...newLineConfig,
383
+ recordKey: newRecord[rowKey]
384
+ }
385
+ }
386
+ } else {
387
+ this.newLineRecordCache = undefined
388
+ }
389
+
390
+ // 插入数据
391
+ if (newLineConfig.position === 'top') {
392
+ dataSource.unshift(newRecord)
393
+ } else {
394
+ dataSource.push(newRecord)
395
+ }
396
+
397
+ // 更新 editableKeys
398
+ const { initializedEditable: { editableKeys, onChange } } = this
399
+ const newKeys = [...editableKeys, newRecord[rowKey]]
400
+ const editableRows = dataSource.filter(item => editableKeys.includes(item[rowKey]))
401
+ onChange?.(newKeys, editableRows)
402
+ },
403
+ /**
404
+ * @desc 获取 column 配置
405
+ * @param col 列
406
+ */
407
+ getColumnProps(col, index) {
408
+ // 筛选 el-column 属性
409
+ const {
410
+ formItemProps,
411
+ renderLabel,
412
+ valueType,
413
+ renderField,
414
+ fieldProps,
415
+ fieldEvents,
416
+ options,
417
+ valueEnum,
418
+ optionLoader,
419
+ renderCellHeader,
420
+ renderCell,
421
+ editable,
422
+ readonly,
423
+ key,
424
+ ...keys
425
+ } = col
426
+ const { sticky } = this
427
+
428
+ const getStickyClassName = (fixed, sticky) => {
429
+ if (!sticky) return ''
430
+ if (fixed === 'left') return 'editable-pro-table__fixed-left'
431
+ if (fixed === 'right') return 'editable-pro-table__fixed-right'
432
+ return ''
433
+ }
434
+
435
+ let className = col['class-name'] || ''
436
+ if (col.fixed && sticky) {
437
+ className += ' ' + getStickyClassName(col.fixed, sticky)
438
+ }
439
+ if (this.calculateOffset.leftIndex === index) {
440
+ className += ' ' + 'editable-pro-table__fixed-start-shadow'
441
+ } else if (this.calculateOffset.rightIndex === index) {
442
+ className += ' ' + 'editable-pro-table__fixed-end-shadow'
443
+ }
444
+
445
+ return {
446
+ ...keys,
447
+ fixed: col.fixed && sticky ? undefined : col.fixed,
448
+ 'class-name': className
449
+ }
450
+ },
451
+ /**
452
+ * @desc 获取待校验的字段
453
+ * @param index 下标
454
+ * @returns {Array}
455
+ */
456
+ getValidateFields(index) {
457
+ return this.columns
458
+ .filter(item => (item.valueType && item.valueType !== 'option') || item.renderField)
459
+ .map(item => `${this.name}.${index}.${item.prop}`)
460
+ },
461
+ /**
462
+ * @desc 校验行
463
+ * @param index 下标
464
+ */
465
+ validateRow(index) {
466
+ return new Promise(async resolve => {
467
+ const fields = this.getValidateFields(index)
468
+ const promises = fields.map(field => new Promise((resolve) => {
469
+ this.getFormRef()?.validateField(field, error => {
470
+ resolve(!error)
471
+ })
472
+ }))
473
+ const res = await Promise.all(promises)
474
+ resolve(!res.some(item => !item))
475
+ })
476
+ },
477
+ /**
478
+ * @desc 验证是否可以开始编辑
479
+ * @returns {Boolean}
480
+ */
481
+ validateCanStartEdit() {
482
+ const { initializedEditable: { type, editableKeys, onlyOneLineEditorAlertMessage } } = this
483
+ if (editableKeys.length && type === 'single') {
484
+ this.$message.warning(onlyOneLineEditorAlertMessage)
485
+ return false
486
+ }
487
+
488
+ return true
489
+ },
490
+ /**
491
+ * @desc 退出编辑
492
+ * @param recordKey
493
+ */
494
+ clearEditableState(recordKey) {
495
+ const { initializedEditable: { editableKeys, onChange } } = this
496
+ if (!editableKeys.includes(recordKey)) {
497
+ return true
498
+ }
499
+ const newKeys = editableKeys.filter(item => item !== recordKey)
500
+ onChange?.(newKeys)
501
+ },
502
+ /**
503
+ * @desc 清除新增行缓存
504
+ * @param recordKey
505
+ */
506
+ clearNewLineCache(recordKey) {
507
+ if (this.newLineRecordCache?.options.recordKey === recordKey) {
508
+ this.newLineRecordCache = null
509
+ }
510
+ },
511
+ /**
512
+ * @desc 取消编辑
513
+ * @param {String | Number} recordKey 值
514
+ * @param {Object} editRow 行数据
515
+ * @param {Object} originRow 初始行数据
516
+ */
517
+ async cancelEditable(recordKey, editRow) {
518
+ try {
519
+ const originRow = this.preEditRows.get(recordKey)
520
+ await this.editable.onCancel?.(recordKey, editRow, originRow)
521
+
522
+ // 退出编辑
523
+ this.clearEditableState(recordKey)
524
+
525
+ // 清除新增行缓存
526
+ this.clearNewLineCache(recordKey)
527
+ } catch (err) {
528
+ console.error('err', err)
529
+ }
530
+
531
+ return true
532
+ },
533
+ /**
534
+ * @desc 查找行数据
535
+ * @param recordKey
536
+ */
537
+ findRecordByKey(recordKey) {
538
+ const dataSource = this.form[this.name]
539
+ const record = dataSource.find(item => item[this.rowKey] === recordKey)
540
+ return JSON.parse(JSON.stringify(record))
541
+ },
542
+ /**
543
+ * @desc 开始编辑指定字段
544
+ * @param {String | Number} recordKey 值
545
+ * @returns {Boolean}
546
+ */
547
+ startEditable(recordKey) {
548
+ if (!this.validateCanStartEdit()) {
549
+ return false
550
+ }
551
+
552
+ const { initializedEditable: { editableKeys, onChange } } = this
553
+
554
+ const isAlreadyEditable = editableKeys?.some(key => key === recordKey)
555
+
556
+ if (!isAlreadyEditable) {
557
+ onChange?.([...editableKeys, recordKey])
558
+ // 更新 preEditRows
559
+ this.preEditRows.set(recordKey, this.findRecordByKey(recordKey))
560
+ }
561
+
562
+ return true
563
+ },
564
+ /**
565
+ * @desc 删除
566
+ * @param recordKey
567
+ */
568
+ filterByRecordKey(recordKey) {
569
+ const { form, name, rowKey } = this
570
+ const dataSource = form[name]
571
+ const index = dataSource.findIndex(item => item[rowKey] === recordKey)
572
+ if (index !== -1) {
573
+ dataSource.splice(index, 1)
574
+ }
575
+ },
576
+ /**
577
+ * @desc 取消
578
+ * @param recordKey
579
+ * @param index
580
+ */
581
+ deleteOrResetRow(recordKey, index) {
582
+ const { initializedCreatorProps: { newRecordType } } = this
583
+ const preEditRow = this.preEditRows.get(recordKey)
584
+ if (preEditRow) {
585
+ // 重置为默认值
586
+ const { form, name, rowKey } = this
587
+ const dataSource = form[name]
588
+ const index = dataSource.findIndex(item => item[rowKey] === recordKey)
589
+ if (index !== -1) {
590
+ dataSource.splice(index, 1, preEditRow)
591
+ }
592
+ } else {
593
+ if (newRecordType !== 'dataSource') {
594
+ // 没有历史值 则删除
595
+ this.filterByRecordKey(recordKey)
596
+ } else {
597
+ // 重置为新增的初始值
598
+ const { initializedCreatorProps: { record }, form, name, rowKey } = this
599
+ const dataSource = form[name]
600
+ const newRecord = {
601
+ ...this.getInitialValues(),
602
+ ...(typeof record === 'function' ? record(index, dataSource) : record)
603
+ }
604
+ // 防止 rowKey 覆盖
605
+ delete newRecord[rowKey]
606
+ this.setRowData(index, newRecord)
607
+ }
608
+ }
609
+ },
610
+ /**
611
+ * @desc 获取 form ref
612
+ */
613
+ getFormRef() {
614
+ return this.formRef || this.$refs.formRef
615
+ },
616
+ /**
617
+ * @desc 获取 table ref
618
+ */
619
+ getTableRef() {
620
+ return this.$refs.editableProTableRef
621
+ },
622
+ /**
623
+ * @desc 获取行数据
624
+ */
625
+ getRowData(rowIndex) {
626
+ const dataSource = this.form[this.name]
627
+ if (typeof rowIndex === 'number' && rowIndex < dataSource.length) {
628
+ return dataSource[rowIndex]
629
+ } else {
630
+ return dataSource.find(item => item[this.rowKey] === rowIndex)
631
+ }
632
+ },
633
+ /**
634
+ * @desc 获取整个 table 的数据
635
+ */
636
+ getRowsData() {
637
+ return this.form[this.name]
638
+ },
639
+ /**
640
+ * @desc 设置一行的数据
641
+ */
642
+ setRowData(rowIndex, data) {
643
+ const dataSource = this.form[this.name]
644
+ if (typeof rowIndex === 'number' && rowIndex < dataSource.length) {
645
+ console.log({ ...dataSource[rowIndex], ...data })
646
+ dataSource.splice(rowIndex, 1, { ...dataSource[rowIndex], ...data })
647
+ } else {
648
+ const index = dataSource.findIndex(item => item[this.rowKey] === rowIndex)
649
+ if (index !== -1) {
650
+ dataSource.splice(index, 1, { ...dataSource[index], ...data })
651
+ }
652
+ }
653
+ },
654
+ /**
655
+ * @desc cellStyle
656
+ */
657
+ getCellStyle({ row, column, rowIndex, columnIndex }, parentCellStyle) {
658
+ const parentStyle = parentCellStyle?.({ row, column, rowIndex, columnIndex })
659
+ const childStyle = this.getStickyStyle(columnIndex, this.initializedColumns[columnIndex].fixed)
660
+
661
+ if (typeof parentStyle === 'string') {
662
+ let cellStyleString = ''
663
+ cellStyleString += parentStyle + ';'
664
+
665
+ if (childStyle) {
666
+ const childStyleString = Object.entries(childStyle)
667
+ .map(([key, value]) => {
668
+ return `${key}: ${value};`
669
+ })
670
+ cellStyleString += childStyleString
671
+ }
672
+
673
+ return cellStyleString
674
+ }
675
+
676
+ if (parentStyle instanceof Object) {
677
+ return {
678
+ ...parentStyle,
679
+ ...(childStyle || {})
680
+ }
681
+ }
682
+
683
+ return childStyle
684
+ },
685
+ /**
686
+ * @desc 获取 sticky 的样式
687
+ * @param {Number} index 下标
688
+ * @param {String} fixed 固定位置
689
+ */
690
+ getStickyStyle(index, fixed) {
691
+ const offset = this.calculateOffset.offset[index]
692
+ if (offset !== undefined) {
693
+ return {
694
+ [fixed]: `${offset}px`
695
+ }
696
+ }
697
+
698
+ return
699
+ },
700
+ },
701
+ }
702
+ </script>
703
+
704
+ <style lang="less" scoped>
705
+ .btn-add-box {
706
+ padding: 0 10px;
707
+ position: sticky;
708
+ left: 0;
709
+
710
+ &::after {
711
+ content: '';
712
+ display: inline-block;
713
+ width: 100%;
714
+ height: 1px;
715
+ background-color: #EBEEF5;
716
+ position: absolute;
717
+ left: 0;
718
+ bottom: 0;
719
+ }
720
+ }
721
+
722
+ .editable-pro-table {
723
+ ::v-deep {
724
+ .editable-pro-table__fixed-left,
725
+ .editable-pro-table__fixed-right {
726
+ position: sticky;
727
+ background-color: #fff;
728
+ z-index: 2;
729
+ }
730
+
731
+ th.el-table__cell,
732
+ td.el-table__cell .cell {
733
+ overflow: unset;
734
+ }
735
+
736
+ td.el-table__cell:has(.is-editable) {
737
+ padding: 18px 0;
738
+ }
739
+ }
740
+
741
+ &.el-table--small {
742
+ ::v-deep td.el-table__cell:has(.is-editable) {
743
+ padding: 16px 0;
744
+ }
745
+ }
746
+ }
747
+ </style>
748
+
749
+ <style lang="less">
750
+ /* 防止外部 el-form-item 校验错误影响 */
751
+ /* start */
752
+ .el-form-item.is-error .editable-pro-table .el-input__inner {
753
+ border-color: #DCDFE6;
754
+
755
+ &:focus {
756
+ border-color: #DCDFE6;
757
+ }
758
+ }
759
+
760
+ .editable-pro-table .el-form-item.is-error .el-input__inner {
761
+ border-color: #F56C6C;
762
+ }
763
+ /* end */
764
+
765
+ /* sticky 滚动样式 */
766
+ /* start */
767
+ .editable-pro-table {
768
+ &:has(.el-table__body-wrapper.is-scrolling-middle),
769
+ &:has(.el-table__body-wrapper.is-scrolling-right),
770
+ .el-table__body-wrapper.is-scrolling-middle,
771
+ .el-table__body-wrapper.is-scrolling-right {
772
+ .editable-pro-table__fixed-start-shadow::after {
773
+ inset-inline-start: 100%;
774
+ position: absolute;
775
+ top: 0px;
776
+ width: 30px;
777
+ height: 100%;
778
+ content: "";
779
+ box-shadow: inset 10px 0 8px -8px rgba(5, 5, 5, 0.06);
780
+ pointer-events: none;
781
+ transition: box-shadow 0.3s;
782
+ z-index: 4;
783
+ }
784
+ }
785
+
786
+ &:has(.el-table__body-wrapper.is-scrolling-left),
787
+ &:has(.el-table__body-wrapper.is-scrolling-middle),
788
+ .el-table__body-wrapper.is-scrolling-left,
789
+ .el-table__body-wrapper.is-scrolling-middle {
790
+ .editable-pro-table__fixed-end-shadow::before {
791
+ position: absolute;
792
+ top: 0px;
793
+ inset-inline-end: 100%;
794
+ width: 30px;
795
+ height: 100%;
796
+ content: "";
797
+ box-shadow: inset -10px 0 8px -8px rgba(5, 5, 5, 0.06);
798
+ pointer-events: none;
799
+ transition: box-shadow 0.3s;
800
+ }
801
+ }
802
+ }
803
+ /* end */
804
+ </style>
805
+