el-plus-crud 0.0.97 → 0.0.99
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/CHANGELOG.md +4 -0
- package/README.md +2 -110
- package/dist/el-plus-crud.mjs +2115 -2097
- package/lib/components/el-plus-form/ElPlusForm.vue +32 -4
- package/lib/components/el-plus-form/components/ElPlusFormImage.vue +6 -7
- package/lib/components/el-plus-form/components/ElPlusFormNumber.vue +1 -0
- package/lib/components/el-plus-form/components/ElPlusFormStatus.vue +2 -2
- package/lib/components/el-plus-form/components/ElPlusFormTag.vue +2 -2
- package/lib/components/el-plus-form/components/ElPlusFormText.vue +2 -2
- package/lib/components/el-plus-form/components/ElPlusFormUpload.vue +22 -17
- package/lib/components/el-plus-table/ElPlusTable.vue +13 -10
- package/lib/components/el-plus-table/components/header.vue +10 -4
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/types/index.d.ts +4 -2
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
<el-row :gutter="10" v-for="(formList, index) in attrMapToTableList" :key="index" :style="{ marginRight: isTable ? '20px' : 0 }">
|
|
7
7
|
<el-col v-for="(formItem, y) in formList" :key="index + '-' + y + '-' + formItem.field" :xs="24" :sm="24" :md="formItem.colspan && formItem.colspan >= column ? 24 : column >= 2 ? 12 : 24" :lg="formItem.colspan && formItem.colspan >= column ? 24 : Math.floor((24 / column) * (formItem.colspan || 1))" :xl="formItem.colspan && formItem.colspan >= column ? 24 : Math.floor((24 / column) * (formItem.colspan || 1))">
|
|
8
8
|
<div v-if="formItem._vif" class="el-plus-form-column-panel" :style="{ 'justify-content': isTable ? 'flex-end' : 'flex-start' }">
|
|
9
|
-
<el-form-item style="min-height: 40px; display: flex" :
|
|
9
|
+
<el-form-item style="min-height: 40px; display: flex" :prop="formItem.field" :style="{ width: formItem._attrs?.width || formItem.width || (isTable ? '150px' : '100%') }">
|
|
10
|
+
<template #label>
|
|
11
|
+
<div v-if="showLabel && formItem.showLabel !== false" class="crud-form-label" :style="{ width: formItem.labelWidth || computedFormAttrs._labelWidth || (isDialog ? '100px' : '120px') }">
|
|
12
|
+
<span :class="{ required: formItem.required }">
|
|
13
|
+
{{ formItem._label }}
|
|
14
|
+
</span>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
10
17
|
<component style="min-width: 80px; width: 100%; flex: 1" :is="formItem._type" :formData="props.modelValue" :disabled="formItem._disabled ?? disabled ?? false" v-bind="formItem._attrs" :desc="formItem" :ref="setComponentRef" :field="formItem.field" v-model="props.modelValue[formItem.field || '']" :isTable="isTable" @validateThis="() => handelValidateThis(formItem.field || '')"></component>
|
|
11
18
|
<div class="el-plus-form-tip" v-if="formItem._tip" v-html="formItem._tip" />
|
|
12
19
|
</el-form-item>
|
|
@@ -38,7 +45,7 @@ export default {
|
|
|
38
45
|
}
|
|
39
46
|
</script>
|
|
40
47
|
<script lang="ts" setup>
|
|
41
|
-
import { ref, computed, useAttrs, nextTick, onMounted, watch, inject } from 'vue'
|
|
48
|
+
import { ref, computed, useAttrs, nextTick, onMounted, watch, inject, Ref } from 'vue'
|
|
42
49
|
import { castArray, isMobile, time, cloneDeep, throttle, isPromiseLike } from './util'
|
|
43
50
|
import * as validates from './util/validate'
|
|
44
51
|
import { typeList } from './components/index'
|
|
@@ -185,7 +192,7 @@ const formLayout = computed(() => ({ display: 'flex', flexDirection: props.isTab
|
|
|
185
192
|
const computedFormAttrs = computed(() => {
|
|
186
193
|
return {
|
|
187
194
|
...props.formAttrs,
|
|
188
|
-
|
|
195
|
+
_labelWidth: props.labelWidth === 'auto' ? (props.isDialog ? '100px' : '120px') : parseInt(props.labelWidth + '') + 'px',
|
|
189
196
|
// validateOnRuleChange: false,
|
|
190
197
|
disabled: props.disabled || innerIsLoading.value,
|
|
191
198
|
rules: computedRules,
|
|
@@ -205,7 +212,7 @@ const computedRules = computed(() => {
|
|
|
205
212
|
if (props.formDesc) {
|
|
206
213
|
Object.keys(props.formDesc).map((field: any) => {
|
|
207
214
|
if (!tempRules[field]) tempRules[field] = []
|
|
208
|
-
let required = false as boolean | ((data?: any) => boolean)
|
|
215
|
+
let required = false as boolean | ((data?: any) => boolean) | Ref<boolean>
|
|
209
216
|
if (props.formDesc && props.formDesc[field]) {
|
|
210
217
|
required = (props.formDesc && props.formDesc[field].required) || false
|
|
211
218
|
}
|
|
@@ -223,6 +230,11 @@ const computedRules = computed(() => {
|
|
|
223
230
|
tempRules[field].push(item)
|
|
224
231
|
})
|
|
225
232
|
}
|
|
233
|
+
// 这里判断一下rules中是否有required
|
|
234
|
+
if (tempRules[field].find((item: any) => item.required)) {
|
|
235
|
+
// 设置必填
|
|
236
|
+
props.formDesc[field].required = true
|
|
237
|
+
}
|
|
226
238
|
} else if (required) {
|
|
227
239
|
let rules = 'notAllBlank'
|
|
228
240
|
switch (props.formDesc[field].type) {
|
|
@@ -820,10 +832,26 @@ defineExpose({ fid: props.fid, submit: handleSubmitForm, getData: getFormData, v
|
|
|
820
832
|
.el-plus-form-column-panel {
|
|
821
833
|
& > .el-form-item--default {
|
|
822
834
|
margin-bottom: 18px !important;
|
|
835
|
+
// & > .el-form-item__label-wrap {
|
|
823
836
|
& > .el-form-item__label {
|
|
824
837
|
line-height: 40px;
|
|
825
838
|
margin-bottom: 0;
|
|
839
|
+
width: auto !important;
|
|
840
|
+
&::before {
|
|
841
|
+
content: '' !important;
|
|
842
|
+
}
|
|
843
|
+
.crud-form-label {
|
|
844
|
+
text-align: right;
|
|
845
|
+
.required {
|
|
846
|
+
&::before {
|
|
847
|
+
content: '*';
|
|
848
|
+
color: var(--el-color-danger);
|
|
849
|
+
margin-right: 4px;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
826
853
|
}
|
|
854
|
+
// }
|
|
827
855
|
}
|
|
828
856
|
}
|
|
829
857
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="ele-form-image">
|
|
3
3
|
<template v-if="imagLIst && imagLIst.length > 0">
|
|
4
|
-
<
|
|
4
|
+
<template v-for="(image, i) in imagLIst" :key="image + i">
|
|
5
|
+
<el-image :class="desc.class" :src="image" :preview-src-list="attrs.isShowPreview === false ? null : imagLIst" :initial-index="i" v-bind="attrs" :style="styles" v-on="onEvents" :fit="attrs.fit || 'cover'" />
|
|
6
|
+
</template>
|
|
5
7
|
</template>
|
|
6
8
|
<div v-else>
|
|
7
|
-
<span class="no-img-tip"
|
|
9
|
+
<span class="no-img-tip">-</span>
|
|
8
10
|
</div>
|
|
9
11
|
</div>
|
|
10
12
|
</template>
|
|
@@ -17,12 +19,9 @@ export default {
|
|
|
17
19
|
}
|
|
18
20
|
</script>
|
|
19
21
|
<script lang="ts" setup>
|
|
20
|
-
import { ref, computed, useAttrs, onBeforeMount
|
|
22
|
+
import { ref, computed, useAttrs, onBeforeMount } from 'vue'
|
|
21
23
|
import { getAttrs, getEvents } from '../mixins'
|
|
22
24
|
|
|
23
|
-
// 格式化
|
|
24
|
-
const format = inject('format') as any
|
|
25
|
-
|
|
26
25
|
const props = defineProps<{
|
|
27
26
|
modelValue?: Array<any> | string | null
|
|
28
27
|
field?: string
|
|
@@ -49,7 +48,7 @@ const imagLIst = computed(() => {
|
|
|
49
48
|
return props.modelValue.map((item) => item.shareUrl || item.furl)
|
|
50
49
|
}
|
|
51
50
|
} else if (typeof props.modelValue === 'string') {
|
|
52
|
-
return props.modelValue.split(',')
|
|
51
|
+
return props.modelValue.split(',')
|
|
53
52
|
} else {
|
|
54
53
|
// console.log('unknown image Type.....')
|
|
55
54
|
}
|
|
@@ -70,7 +70,7 @@ watch(
|
|
|
70
70
|
() => props.modelValue,
|
|
71
71
|
async () => {
|
|
72
72
|
if (!props.desc.format) {
|
|
73
|
-
formatValue.value = props.modelValue === '' ? props.desc.default ?? '
|
|
73
|
+
formatValue.value = props.modelValue === '' ? props.desc.default ?? '-' : props.modelValue ?? props.desc.default ?? '-'
|
|
74
74
|
} else {
|
|
75
75
|
if (typeof props.desc.format === 'function') {
|
|
76
76
|
// 如果有方法类型的判断,则需要启用动态监测
|
|
@@ -78,7 +78,7 @@ watch(
|
|
|
78
78
|
} else if (typeof props.desc.format === 'string') {
|
|
79
79
|
formatValue.value = format[props.desc.format] ? format[props.desc.format](props.modelValue, props.formData || {}, props.field) : '--'
|
|
80
80
|
} else {
|
|
81
|
-
formatValue.value = props.modelValue || '
|
|
81
|
+
formatValue.value = props.modelValue || '-'
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
},
|
|
@@ -62,7 +62,7 @@ watch(
|
|
|
62
62
|
() => props.modelValue,
|
|
63
63
|
async () => {
|
|
64
64
|
if (!props.desc.format) {
|
|
65
|
-
formatValue.value = props.modelValue === '' ? '
|
|
65
|
+
formatValue.value = props.modelValue === '' ? '-' : props.modelValue ?? '-'
|
|
66
66
|
} else {
|
|
67
67
|
if (typeof props.desc.format === 'function') {
|
|
68
68
|
// 如果有方法类型的判断,则需要启用动态监测
|
|
@@ -70,7 +70,7 @@ watch(
|
|
|
70
70
|
} else if (typeof props.desc.format === 'string') {
|
|
71
71
|
formatValue.value = (await format)[props.desc.format](props.modelValue, props.formData || {}, props.field)
|
|
72
72
|
} else {
|
|
73
|
-
formatValue.value = props.modelValue || '
|
|
73
|
+
formatValue.value = props.modelValue || '-'
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
},
|
|
@@ -80,7 +80,7 @@ watch(
|
|
|
80
80
|
() => props.modelValue,
|
|
81
81
|
async () => {
|
|
82
82
|
if (!props.desc.format) {
|
|
83
|
-
formatValue.value = props.modelValue === '' ? props.desc.default ?? '
|
|
83
|
+
formatValue.value = props.modelValue === '' ? props.desc.default ?? '-' : props.modelValue ?? props.desc.default ?? '-'
|
|
84
84
|
} else {
|
|
85
85
|
if (typeof props.desc.format === 'function') {
|
|
86
86
|
// 如果有方法类型的判断,则需要启用动态监测
|
|
@@ -89,7 +89,7 @@ watch(
|
|
|
89
89
|
} else if (typeof props.desc.format === 'string') {
|
|
90
90
|
formatValue.value = format[props.desc.format] ? format[props.desc.format](props.modelValue, props.formData, props.field) : '--'
|
|
91
91
|
} else {
|
|
92
|
-
formatValue.value = props.modelValue || '
|
|
92
|
+
formatValue.value = props.modelValue || '-'
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
},
|
|
@@ -223,7 +223,11 @@ async function handelUploadSuccess(response: any, file: any) {
|
|
|
223
223
|
file.raw.path = response.furl || file.path
|
|
224
224
|
}
|
|
225
225
|
file.raw.shareUrl = file.path
|
|
226
|
-
|
|
226
|
+
if (props.desc.upType !== 'file') {
|
|
227
|
+
file.url = getFileIcon(file.raw)
|
|
228
|
+
} else {
|
|
229
|
+
file.url = response.furl || file.path
|
|
230
|
+
}
|
|
227
231
|
handelListChange(file, 1)
|
|
228
232
|
}
|
|
229
233
|
|
|
@@ -232,18 +236,16 @@ async function handelUploadSuccess(response: any, file: any) {
|
|
|
232
236
|
* @param file
|
|
233
237
|
*/
|
|
234
238
|
function getFileIcon(file?: any): string {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (suffix) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
for (let
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return iconMap[fileTypes.suffixTypes[i].type]
|
|
246
|
-
}
|
|
239
|
+
const fileUrl = file.shareUrl || file.furl || file.path || file.url
|
|
240
|
+
const suffix = (file?.suffix || fileUrl.substring(fileUrl.lastIndexOf('.')) || '') as string
|
|
241
|
+
if (suffix) {
|
|
242
|
+
if (fileTypes.imageSuffixes.indexOf(suffix.toLocaleLowerCase()) >= 0) {
|
|
243
|
+
return fileUrl
|
|
244
|
+
}
|
|
245
|
+
for (let i = 0; i < fileTypes.suffixTypes.length; i++) {
|
|
246
|
+
for (let j = 0; j < fileTypes.suffixTypes[i].suffixes.length; j++) {
|
|
247
|
+
if (fileTypes.suffixTypes[i].suffixes[j] === suffix) {
|
|
248
|
+
return iconMap[fileTypes.suffixTypes[i].type]
|
|
247
249
|
}
|
|
248
250
|
}
|
|
249
251
|
}
|
|
@@ -270,7 +272,7 @@ function handelListChange(item: UploadUserFile, type: 0 | 1) {
|
|
|
270
272
|
currentValue.value.push({
|
|
271
273
|
name: item.name,
|
|
272
274
|
furl: (item.raw as any)?.path || item.url,
|
|
273
|
-
url: getFileIcon(item.raw),
|
|
275
|
+
url: props.desc.upType !== 'file' ? getFileIcon(item.raw) : item.url,
|
|
274
276
|
fsize: item.size,
|
|
275
277
|
uid: item.uid,
|
|
276
278
|
mimeType: item.raw?.type,
|
|
@@ -361,9 +363,12 @@ watch(
|
|
|
361
363
|
} else {
|
|
362
364
|
currentValue.value =
|
|
363
365
|
data?.map((item: IOssInfo) => {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
366
|
+
if (props.desc.upType !== 'file') {
|
|
367
|
+
item.url = getFileIcon(item)
|
|
368
|
+
item.furl = getFileIcon(item)
|
|
369
|
+
}
|
|
370
|
+
item.suffix = item.suffix || item.url?.substring(item.url.lastIndexOf('.'))
|
|
371
|
+
item.previewUrl = item.furl || item.url
|
|
367
372
|
return item
|
|
368
373
|
}) || []
|
|
369
374
|
}
|
|
@@ -206,7 +206,7 @@ const listLoading = ref(false)
|
|
|
206
206
|
const size = defaultConf.size || 'default'
|
|
207
207
|
|
|
208
208
|
// 顶部查询条件数据缓存
|
|
209
|
-
const topQueryData = ref({} as any)
|
|
209
|
+
// const topQueryData = ref({} as any)
|
|
210
210
|
|
|
211
211
|
// 数据
|
|
212
212
|
let toolFormData = reactive({} as any)
|
|
@@ -497,8 +497,8 @@ async function getListQueryData() {
|
|
|
497
497
|
let queryMap = {
|
|
498
498
|
// 封装查询条件
|
|
499
499
|
// ...route.query,
|
|
500
|
-
// ...
|
|
501
|
-
...
|
|
500
|
+
// ...topQueryData.value,
|
|
501
|
+
...tableHeaderRef.value.getData(),
|
|
502
502
|
...(typeof props.tableConfig.queryMap === 'function' ? await props.tableConfig.queryMap() : props.tableConfig.queryMap),
|
|
503
503
|
t_: new Date().getTime()
|
|
504
504
|
} as any
|
|
@@ -643,10 +643,6 @@ async function loadData(isInit: Boolean) {
|
|
|
643
643
|
dataResult = dataPage[props.tableConfig?.fetchMap?.list || 'records'] || null
|
|
644
644
|
}
|
|
645
645
|
tableData.value = dataResult
|
|
646
|
-
if (isInit) {
|
|
647
|
-
// 调用父类init
|
|
648
|
-
emits('inited', tableData)
|
|
649
|
-
}
|
|
650
646
|
// 如果是树形结构
|
|
651
647
|
if (props.type === 'expand') {
|
|
652
648
|
treeIndexList.splice(0, treeIndexList.length)
|
|
@@ -698,8 +694,12 @@ async function reload(isTab: boolean = false) {
|
|
|
698
694
|
* 处理顶部条件表单筛选
|
|
699
695
|
*/
|
|
700
696
|
async function handelTopQuery() {
|
|
701
|
-
topQueryData.value = cloneDeep(tableHeaderRef.value.getData())
|
|
702
|
-
|
|
697
|
+
// topQueryData.value = cloneDeep(tableHeaderRef.value.getData())
|
|
698
|
+
let tempQueryData = await getListQueryData()
|
|
699
|
+
if (props.tableConfig?.toolbar?.formConfig?.beforeRequest) {
|
|
700
|
+
tempQueryData = props.tableConfig?.toolbar?.formConfig?.beforeRequest(JSON.parse(JSON.stringify(tempQueryData))) || tempQueryData
|
|
701
|
+
}
|
|
702
|
+
if (tempQueryData) emits('queryChange', tempQueryData)
|
|
703
703
|
reload()
|
|
704
704
|
}
|
|
705
705
|
|
|
@@ -741,7 +741,10 @@ if (props.isDIYMain) {
|
|
|
741
741
|
}
|
|
742
742
|
|
|
743
743
|
onMounted(() => {
|
|
744
|
-
|
|
744
|
+
// toolbar.formConfig
|
|
745
|
+
if (!(Object.keys(props.tableConfig?.toolbar?.formConfig || {}).length || props.tableConfig?.tbName)) {
|
|
746
|
+
reload()
|
|
747
|
+
}
|
|
745
748
|
})
|
|
746
749
|
|
|
747
750
|
defineExpose({ reload, tableData, changeSelect, resetSelect, initCol })
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<template v-if="props.toolbar && Object.keys(props.toolbar || {}).length">
|
|
4
4
|
<el-form :inline="true" class="el-plus-table-header-form" :style="{ justifyContent: !props.toolbar.formConfig && props.toolbar.btnRight ? 'flex-end' : 'space-between' }">
|
|
5
5
|
<div v-if="props.toolbar.formConfig" class="el-plus-table-form-items">
|
|
6
|
-
<ElPlusForm ref="elPlusFormRef" v-bind="formConfig" v-model="props.modelValue"
|
|
6
|
+
<ElPlusForm ref="elPlusFormRef" v-bind="formConfig" v-model="props.modelValue" :requestFn="handelQueryData" :showBtns="false" :isTable="true">
|
|
7
7
|
<template #row>
|
|
8
8
|
<div class="table-header-form-btns">
|
|
9
9
|
<ElPlusFormBtn type="primary" icon="ele-Search" :loading="loading" :desc="{ label: '查询', on: { click: handelSearch }, size }" />
|
|
@@ -193,7 +193,7 @@ async function handelDownload({ callBack }: IBtnBack) {
|
|
|
193
193
|
* 处理搜索
|
|
194
194
|
*/
|
|
195
195
|
function handelSearch() {
|
|
196
|
-
elPlusFormRef.value
|
|
196
|
+
elPlusFormRef.value?.submit()
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
|
@@ -202,7 +202,7 @@ function handelSearch() {
|
|
|
202
202
|
function handelReset() {
|
|
203
203
|
elPlusFormRef.value.clear()
|
|
204
204
|
nextTick(() => {
|
|
205
|
-
elPlusFormRef.value
|
|
205
|
+
elPlusFormRef.value?.submit()
|
|
206
206
|
})
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -251,7 +251,13 @@ function initCol() {
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
onMounted(() => {
|
|
254
|
+
onMounted(() => {
|
|
255
|
+
nextTick(() => {
|
|
256
|
+
setTimeout(() => {
|
|
257
|
+
handelSearch()
|
|
258
|
+
}, 200)
|
|
259
|
+
})
|
|
260
|
+
})
|
|
255
261
|
|
|
256
262
|
defineExpose({ getData: () => elPlusFormRef.value?.getData(), initCol })
|
|
257
263
|
</script>
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "el-plus-crud",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.99",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "el-plus-crud",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.99",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@element-plus/icons-vue": "^2.1.0",
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Ref } from 'vue'
|
|
2
|
+
|
|
1
3
|
// 基础类型
|
|
2
4
|
export type IBaseObj = IBaseObj
|
|
3
5
|
|
|
@@ -79,14 +81,14 @@ export type IDescItem = {
|
|
|
79
81
|
*/
|
|
80
82
|
export interface IFormDescItem extends IDescItem {
|
|
81
83
|
field?: string
|
|
82
|
-
disabled?: boolean | ((data?: any) => boolean)
|
|
84
|
+
disabled?: boolean | Ref<boolean> | ((data?: any) => boolean)
|
|
83
85
|
showLabel?: boolean
|
|
84
86
|
labelWidth?: string | number
|
|
85
87
|
tip?: string | ((data?: any) => string)
|
|
86
88
|
size?: string
|
|
87
89
|
placeholder?: string
|
|
88
90
|
attrs?: IBaseObj | ((data?: any) => IBaseObj)
|
|
89
|
-
options?: Array<IFormDescItemOptionItem> | IFetch<Array<IFormDescItemOptionItem>> | string
|
|
91
|
+
options?: Ref<Array<IFormDescItemOptionItem>> | Array<IFormDescItemOptionItem> | (() => Array<IFormDescItemOptionItem>) | IFetch<Array<IFormDescItemOptionItem>> | string
|
|
90
92
|
default?: string | boolean | number
|
|
91
93
|
defaultItem?: { value: string | number; label: string; dataItem?: IBaseObj }
|
|
92
94
|
rules?: string | Array<any>
|