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,404 @@
1
+ <template>
2
+ <el-dialog
3
+ :visible.sync="dialogVisible"
4
+ v-bind="normalizedDialogProps"
5
+ v-on="normalizedDialogEvents"
6
+ >
7
+ <!-- 自定义 dialog title -->
8
+ <!-- start -->
9
+ <template v-if="renderTitle" #title>
10
+ <CustomRender :render="() => renderTitle(form)" />
11
+ </template>
12
+ <!-- end -->
13
+ <el-form
14
+ ref="dialogFormRef"
15
+ :model="form"
16
+ class="pro-form"
17
+ :class="className"
18
+ v-bind="formProps"
19
+ >
20
+ <!-- 栅格布局 -->
21
+ <!-- start -->
22
+ <template v-if="grid">
23
+ <el-row v-bind="rowProps">
24
+ <el-col
25
+ v-for="formItem in normalizedFormItems"
26
+ v-bind="formItem.colProps"
27
+ :key="formItem.prop || formItem.key"
28
+ >
29
+ <!-- 自定义 el-form-item -->
30
+ <!-- start -->
31
+ <slot
32
+ v-if="formItem.customSlot"
33
+ :name="formItem.customSlot === true ? formItem.prop : formItem.customSlot"
34
+ v-bind="{ form }"
35
+ ></slot>
36
+ <CustomRender
37
+ v-else-if="formItem.renderFormItem"
38
+ :render="() => formItem.renderFormItem(form)"
39
+ />
40
+ <!-- end -->
41
+ <!-- ProFormItem -->
42
+ <!-- start -->
43
+ <ProFormItem
44
+ v-else
45
+ :form="form"
46
+ :formItem="formItem"
47
+ >
48
+ <template #[formItem.prop]>
49
+ <slot :name="formItem.prop" v-bind="{ form, formItem }"></slot>
50
+ </template>
51
+ </ProFormItem>
52
+ <!-- end -->
53
+ </el-col>
54
+ </el-row>
55
+ </template>
56
+ <!-- end -->
57
+ <!-- 非栅格布局 -->
58
+ <!-- start -->
59
+ <template v-else>
60
+ <template v-for="formItem in normalizedFormItems">
61
+ <!-- 自定义 el-form-item -->
62
+ <!-- start -->
63
+ <slot
64
+ v-if="formItem.customSlot"
65
+ :name="formItem.customSlot === true ? formItem.prop : formItem.customSlot"
66
+ v-bind="{ form }"
67
+ ></slot>
68
+ <CustomRender
69
+ v-else-if="formItem.renderFormItem"
70
+ :render="() => formItem.renderFormItem(form)"
71
+ :key="formItem.prop || formItem.key"
72
+ />
73
+ <!-- end -->
74
+ <!-- ProFormItem -->
75
+ <!-- start -->
76
+ <ProFormItem
77
+ v-else
78
+ :form="form"
79
+ :formItem="formItem"
80
+ :key="formItem.prop || formItem.key"
81
+ >
82
+ <template #[formItem.prop]>
83
+ <slot :name="formItem.prop" v-bind="{ form, formItem }"></slot>
84
+ </template>
85
+ </ProFormItem>
86
+ <!-- end -->
87
+ </template>
88
+ </template>
89
+ </el-form>
90
+ <!-- end -->
91
+ <!-- submitter -->
92
+ <!-- start -->
93
+ <template v-if="submitter" #footer>
94
+ <Submitter
95
+ :submitter="submitterProps"
96
+ :actions="{ submit, close, reset, resetAllFields }"
97
+ :render="submitter.customRender
98
+ ? (actions, doms) => submitter.customRender(form, actions, doms)
99
+ : null
100
+ "
101
+ />
102
+ </template>
103
+ <!-- end -->
104
+ </el-dialog>
105
+ </template>
106
+
107
+ <script>
108
+ import CustomRender from '@/components/custom-render'
109
+ import ProFormItem from '@/components/pro-form-item'
110
+ import Submitter from './components/Submitter'
111
+ import { setPlaceholder, setSelectOptions, setCascaderOptions } from 'element-ui-pro-components/src/utils/form'
112
+ import { t } from 'element-ui-pro-components/src/locale'
113
+
114
+ export default {
115
+ name: 'DialogForm',
116
+ model: {
117
+ prop: 'visible',
118
+ event: 'close'
119
+ },
120
+ components: {
121
+ CustomRender,
122
+ ProFormItem,
123
+ Submitter
124
+ },
125
+ props: {
126
+ // 是否打开弹框
127
+ visible: {
128
+ type: Boolean,
129
+ default: false
130
+ },
131
+ // 弹框的标题
132
+ title: {
133
+ type: String
134
+ },
135
+ // 自定义弹框标题
136
+ renderTitle: {
137
+ type: Function,
138
+ },
139
+ // 弹框的宽度
140
+ width: {
141
+ type: String
142
+ },
143
+ // el-dialog attributes 的配置
144
+ dialogProps: {
145
+ type: Object,
146
+ default: () => ({})
147
+ },
148
+ // el-dialog events 的配置
149
+ dialogEvents: {
150
+ type: Object,
151
+ default: () => ({})
152
+ },
153
+ // el-form attributes 的配置
154
+ formProps: {
155
+ type: Object,
156
+ default: () => ({})
157
+ },
158
+ // el-form 的类名
159
+ className: {
160
+ type: String
161
+ },
162
+ // 表单项配置
163
+ formItems: {
164
+ type: Array,
165
+ required: true,
166
+ default: () => []
167
+ },
168
+ // 提交按钮相关配置
169
+ submitter: {
170
+ type: [Boolean, Object],
171
+ default: true
172
+ },
173
+ // 开启栅格化模式
174
+ grid: {
175
+ type: Boolean,
176
+ },
177
+ // 开启 grid 模式时传递给 el-row
178
+ rowProps: {
179
+ type: Object,
180
+ default: () => ({ gutter: 8 })
181
+ },
182
+ // 表单默认值
183
+ initialValues: {
184
+ type: Object,
185
+ default: () => ({})
186
+ },
187
+ },
188
+ computed: {
189
+ // 标准化 dialog props
190
+ normalizedDialogProps() {
191
+ const { title, width, dialogProps = {} } = this
192
+ const customClass = dialogProps['custom-class']
193
+ return {
194
+ ...dialogProps,
195
+ 'custom-class': customClass ? `${customClass} dialog-form` : 'dialog-form',
196
+ visible: undefined, // 阻止绑定
197
+ title,
198
+ width,
199
+ }
200
+ },
201
+ // 标准化 dialog events
202
+ normalizedDialogEvents() {
203
+ const { dialogEvents, close } = this
204
+
205
+ const originalClose = dialogEvents.close
206
+ // 包装以下 close 方法,确保执行 close 方法
207
+ if (originalClose) {
208
+ dialogEvents.close = () => {
209
+ originalClose()
210
+ close()
211
+ }
212
+
213
+ return {
214
+ ...dialogEvents
215
+ }
216
+ }
217
+
218
+ return { close }
219
+ },
220
+ // formItems 标准化处理
221
+ normalizedFormItems() {
222
+ return this.formItems
223
+ // 过滤隐藏项
224
+ .filter(item => !item.hideInForm)
225
+ .map(item => {
226
+ const { valueType, fieldProps = {} } = item
227
+ // 设置 placeholder
228
+ setPlaceholder(fieldProps, valueType)
229
+
230
+ // 设置 select options
231
+ setSelectOptions(item, this.cachedOptions)
232
+
233
+ // 设置 cascader options
234
+ setCascaderOptions(fieldProps, item, this.cachedOptions)
235
+
236
+ return {
237
+ ...item,
238
+ fieldProps
239
+ }
240
+ })
241
+ },
242
+ // submitter 标准化处理
243
+ submitterProps() {
244
+ if (this.submitter) {
245
+ // 配置按钮文本
246
+ const defaultTextConfig = {
247
+ cancelText: t('elProComponents.dialogForm.cancel'),
248
+ confirmText: t('elProComponents.dialogForm.confirm')
249
+ }
250
+
251
+ // 对象类型
252
+ if (typeof this.submitter === 'object') {
253
+ return {
254
+ ...defaultTextConfig,
255
+ ...this.submitter
256
+ }
257
+ }
258
+
259
+ // 返回默认配置
260
+ return {
261
+ ...defaultTextConfig
262
+ }
263
+ }
264
+
265
+ return false
266
+ }
267
+ },
268
+ data() {
269
+ return {
270
+ dialogVisible: false, // 是否打开弹框
271
+ cachedOptions: {}, // 下拉数据 { [prop]: res }
272
+ form: this.initForm(), // 表单数据
273
+ }
274
+ },
275
+ watch: {
276
+ // 监听 visible
277
+ visible: {
278
+ handler(newValue) {
279
+ this.dialogVisible = newValue
280
+ },
281
+ immediate: true
282
+ }
283
+ },
284
+ created () {
285
+ // 获取异步数据
286
+ this.getOptions()
287
+ },
288
+ methods: {
289
+ /**
290
+ * @desc 获取异步下拉数据
291
+ */
292
+ getOptions() {
293
+ for (const item of this.formItems) {
294
+ const { prop, optionLoader } = item
295
+ if (typeof optionLoader === 'function') {
296
+ optionLoader().then(res => {
297
+ this.cachedOptions = {
298
+ ...this.cachedOptions,
299
+ [prop]: res
300
+ }
301
+ })
302
+ }
303
+ }
304
+ },
305
+ /**
306
+ * @desc 初始化表单数据
307
+ */
308
+ initForm() {
309
+ const { formItems, initialValues } = this
310
+ const data = formItems.reduce((accu, cur) => {
311
+ const { prop, initialValue } = cur
312
+ if (!prop) {
313
+ return accu
314
+ }
315
+
316
+ return {
317
+ ...accu,
318
+ [prop]: initialValue
319
+ }
320
+ }, {})
321
+
322
+ return { ...initialValues, ...data }
323
+ },
324
+ /**
325
+ * @desc 获取 el-form ref
326
+ * @returns {Object}
327
+ */
328
+ getFormRef() {
329
+ return this.$refs.dialogFormRef
330
+ },
331
+ /**
332
+ * @desc 获取表单数据
333
+ * @returns {Object}
334
+ */
335
+ getForm() {
336
+ return this.form
337
+ },
338
+ /**
339
+ * @desc 手动更新表单数据
340
+ * @param {Object} data 数据
341
+ */
342
+ setFieldsValue(data) {
343
+ this.form = {
344
+ ...this.form,
345
+ ...data
346
+ }
347
+ },
348
+ /**
349
+ * @desc 手动更新单个字段数据
350
+ * @param {String} key 键
351
+ * @param {any} value 值
352
+ */
353
+ setFieldValue(key, value) {
354
+ this.form[key] = value
355
+ },
356
+ /**
357
+ * @desc Dialog 关闭的回调
358
+ */
359
+ close() {
360
+ this.$emit('close', false)
361
+ },
362
+ /**
363
+ * @desc 提交
364
+ */
365
+ submit() {
366
+ this.$refs.dialogFormRef?.validate((valid, object) => {
367
+ if (valid) {
368
+ // 回传给父组件
369
+ this.$emit('onFinish', this.form)
370
+ return
371
+ }
372
+
373
+ // 回传给父组件
374
+ this.$emit('onError', object)
375
+ })
376
+ },
377
+ /**
378
+ * @desc 重置
379
+ */
380
+ async reset() {
381
+ try {
382
+ await this.$refs.dialogFormRef?.resetFields()
383
+ // 回传给父组件
384
+ this.$emit('onReset')
385
+ } catch (err) {
386
+ console.error('err', err)
387
+ }
388
+ },
389
+ /**
390
+ * @desc 重置表单的拓展方法,过滤了非表单项的字段
391
+ */
392
+ resetAllFields() {
393
+ // 清除校验
394
+ this.$refs.dialogFormRef?.clearValidate()
395
+ // 重置数据
396
+ this.form = this.initForm()
397
+ },
398
+ }
399
+ }
400
+ </script>
401
+
402
+ <style scoped>
403
+
404
+ </style>
@@ -0,0 +1,9 @@
1
+ import EditableProTable from './src'
2
+
3
+ // 为组件提供 install 方法
4
+ EditableProTable.install = function(Vue) {
5
+ Vue.component(EditableProTable.name, EditableProTable)
6
+ }
7
+
8
+ // 默认导出组件
9
+ export default EditableProTable
@@ -0,0 +1,203 @@
1
+ <script>
2
+ import { t } from 'element-ui-pro-components/src/locale'
3
+
4
+ export default {
5
+ name: 'Editable',
6
+ props: {
7
+ // 可编辑配置
8
+ editable: {
9
+ type: Object,
10
+ required: true
11
+ },
12
+ actions: {
13
+ type: Object,
14
+ required: true
15
+ },
16
+ validateRow: {
17
+ type: Function
18
+ },
19
+ recordKey: {
20
+ type: [String, Number],
21
+ },
22
+ render: {
23
+ type: Function,
24
+ required: true
25
+ },
26
+ scope: {
27
+ type: Object
28
+ },
29
+ newLineRecordCache: {
30
+ type: Object
31
+ },
32
+ name: {
33
+ type: String
34
+ },
35
+ preEditRows: {
36
+ type: Map
37
+ },
38
+ defaultSize: {
39
+ type: String
40
+ }
41
+ },
42
+ computed: {
43
+ isEditable() {
44
+ const { editable: { editableKeys }, recordKey } = this
45
+ return editableKeys?.some(key => recordKey === key)
46
+ },
47
+ isNewLineRecordCache() {
48
+ return this.newLineRecordCache?.options.recordKey === this.recordKey
49
+ }
50
+ },
51
+ data() {
52
+ return {
53
+ saveLoading: false,
54
+ deleteLoading: false,
55
+ visible: false
56
+ }
57
+ },
58
+ methods: {
59
+ /**
60
+ * @desc 保存
61
+ */
62
+ async save() {
63
+ // 手动销毁
64
+ this.visible = false
65
+ const { validateRow, scope: { row, $index }, recordKey } = this
66
+ const res = await validateRow($index)
67
+ if (!res) {
68
+ return
69
+ }
70
+ try {
71
+ this.saveLoading = true
72
+ const res = await this.editable.onSave?.(recordKey, row, this.preEditRows.get(recordKey))
73
+ this.saveLoading = false
74
+ if (res === false) {
75
+ return
76
+ }
77
+ this.actions.cancelEditable(recordKey, row)
78
+ } catch (err) {
79
+ this.saveLoading = false
80
+ console.error('err', err)
81
+ }
82
+ },
83
+ /**
84
+ * @desc 删除
85
+ */
86
+ async delete() {
87
+ try {
88
+ this.deleteLoading = true
89
+ const { scope: { row }, recordKey } = this
90
+ const res = await this.editable.onDelete?.(recordKey, row)
91
+ this.deleteLoading = false
92
+ if (res === false) {
93
+ return
94
+ }
95
+ this.visible = false
96
+ await this.actions.cancelEditable(recordKey, row)
97
+ this.$emit('delete', recordKey)
98
+ } catch (err) {
99
+ this.deleteLoading = false
100
+ console.error('err', err)
101
+ }
102
+ },
103
+ /**
104
+ * @desc 取消
105
+ */
106
+ async cancel() {
107
+ try {
108
+ // 手动销毁
109
+ this.visible = false
110
+ const { recordKey, scope: { row, $index } } = this
111
+ await this.actions.cancelEditable(recordKey, row)
112
+ this.$emit('cancel', recordKey, $index)
113
+ } catch (err) {
114
+ console.error('err', err)
115
+ }
116
+ }
117
+ },
118
+ render: function(h) {
119
+ const { saveText, deleteText, cancelText, deletePopconfirmMessage } = this.editable
120
+ const { defaultSize } = this
121
+ const doms = {
122
+ save: <el-button class="btn-save" type="text" size={defaultSize} loading={this.saveLoading} onClick={this.save} key="save">{ saveText }</el-button>,
123
+ delete: <el-popover
124
+ placement="top"
125
+ popper-class="editable-pro-table__popover--delete"
126
+ trigger="click"
127
+ value={this.visible}
128
+ onInput={val => this.visible = val}
129
+ key="delete"
130
+ >
131
+ <i class="el-icon-info"></i>
132
+ <span>{deletePopconfirmMessage}</span>
133
+ <div>
134
+ <el-button size="mini" type="text" onClick={() => this.visible = false}>{ t('elProComponents.editableProTable.cancelButtonText') }</el-button>
135
+ <el-button type="primary" size="mini" loading={this.deleteLoading} onClick={this.delete}>{ t('elProComponents.editableProTable.confirmButtonText') }</el-button>
136
+ </div>
137
+ <el-button slot="reference" type="text" size={defaultSize}>{ deleteText }</el-button>
138
+ </el-popover>,
139
+ cancel: <el-button class="btn-cancel" type="text" size={defaultSize} onClick={this.cancel} key="cancel">{ cancelText }</el-button>,
140
+ }
141
+
142
+ const {
143
+ editable:
144
+ { editableKeys, onChange, onSave, onDelete, onCancel, actionRender },
145
+ scope: { row },
146
+ isNewLineRecordCache
147
+ } = this
148
+
149
+ const { recordKey, scope: { $index }, actions: { cancelEditable, addEditRecord }, name, newLineRecordCache } = this
150
+ const config = {
151
+ editableKeys,
152
+ setEditableRowKeys: (keys) => onChange?.(keys),
153
+ recordKey,
154
+ preEditRow: this.preEditRows.get(recordKey),
155
+ index: $index,
156
+ onSave,
157
+ onDelete,
158
+ onCancel,
159
+ cancelEditable,
160
+ newLineConfig: newLineRecordCache,
161
+ saveText,
162
+ deleteText,
163
+ cancelText,
164
+ deletePopconfirmMessage,
165
+ addEditRecord,
166
+ tableName: name
167
+ }
168
+
169
+ const defaultDoms = [doms.save, !isNewLineRecordCache && doms.delete, doms.cancel].filter(Boolean)
170
+ const actionDoms = typeof actionRender === 'function' ? actionRender(row, config, doms) : defaultDoms
171
+
172
+ return <Fragment>
173
+ {this.isEditable ? actionDoms : this.render(this.actions)}
174
+ </Fragment>
175
+ }
176
+ }
177
+ </script>
178
+
179
+ <style scoped>
180
+ .btn-save + span {
181
+ margin-left: 10px;
182
+ }
183
+
184
+ span + :deep(.btn-cancel) {
185
+ margin-left: 10px;
186
+ }
187
+ </style>
188
+
189
+ <style lang="less">
190
+ .editable-pro-table__popover--delete.el-popover {
191
+ min-width: unset;
192
+
193
+ > i {
194
+ color: rgb(255, 153, 0);
195
+ margin-right: 5px;
196
+ }
197
+
198
+ > div {
199
+ margin-top: 10px;
200
+ margin-left: 8px;
201
+ }
202
+ }
203
+ </style>