@neatui/vue 2.10.0 → 2.12.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.
- package/package.json +1 -1
- package/src/components/basic/LayerView/Layer.vue +0 -16
- package/src/components/display/Calendar.vue +14 -14
- package/src/components/display/CalendarReg.vue +14 -14
- package/src/components/display/Tree.vue +6 -6
- package/src/components/form/Cascader.vue +20 -20
- package/src/components/form/DatePicker.vue +8 -9
- package/src/components/form/DateRangePicker@v3.vue +5 -5
- package/src/components/form/DateRangeView@v3.vue +9 -9
- package/src/components/form/DateView.vue +14 -14
- package/src/components/form/DateView@v2.vue +14 -14
- package/src/components/form/DateView@v3.vue +17 -15
- package/src/components/form/Input@v3.vue +2 -2
- package/src/components/form/MoreSelect@v3.vue +27 -8
- package/src/components/form/MoreSelectList.vue +1 -1
- package/src/components/form/MoreSelectPanel@v3.vue +4 -4
- package/src/components/form/MoreSelectPicker.vue +1 -1
- package/src/components/form/MoreSelectTags.vue +1 -1
- package/src/components/form/PageMoreSelect.vue +15 -15
- package/src/components/form/PageSelect.vue +17 -17
- package/src/components/form/SearchMoreSelect.vue +1 -1
- package/src/components/form/SearchSelect@v3.vue +4 -4
- package/src/components/form/Select@v3.vue +13 -10
- package/src/components/form/SelectList.vue +8 -8
- package/src/components/form/SelectPicker.vue +7 -7
- package/src/components/form/SelectTags.vue +7 -7
- package/src/components/form/SelectTree/SelectTree@v1.vue +6 -6
- package/src/components/form/Switch.vue +38 -103
- package/src/components/form/Textarea@v2.vue +275 -0
- package/src/components/form/TimeView.vue +14 -14
- package/src/components/form/Upload.vue +52 -9
- package/src/components/form/date.ts +321 -0
- package/src/components/form/index.ts +2 -2
- package/src/components/form/number.ts +3 -0
- package/src/components/form/type.ts +224 -0
- package/src/components/loader/FormLoader/FormLoader@v2.vue +20 -20
- package/src/components/loader/FormLoader/FormLoader@v3.vue.backup +372 -291
- package/src/components/loader/FormLoader/FormRender@v3.vue.backup +4 -0
- package/src/components/loader/FormLoader/NodeLoader.vue +85 -0
- package/src/components/loader/FormLoader@v1/FormLoader.vue +1 -1
- package/src/components/loader/FormLoader@v1/FormRender.vue +49 -24
- package/src/components/loader/LayerLoader/LayerLoader.vue +1 -1
- package/src/components/loader/LimitLoader/LimitLoader@v3.vue +1 -1
- package/src/components/loader/MoveLoader/MoveLoader.vue +8 -8
- package/src/components/loader/TableLoader/TableLoader.vue +14 -9
- package/src/components/loader/TableLoader/TableRender.vue +100 -70
- package/src/components/loader/index.ts +1 -1
- package/src/components/tools/Pagination@a.vue +1 -1
- package/tsconfig.json +1 -1
- package/src/components/loader/FormLoader/index.ts +0 -2
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<template v-for="(item, index) in $nodes" :key="item.paths">
|
|
3
|
+
<div class="fekit-node-loader" :data-level="level" :data-index="index" :data-paths="item.paths" v-bind="item.attrs" v-on="item.$events" v-html="item.value"></div>
|
|
4
|
+
<NodeLoader v-if="item.child" :nodes="item.child" :level="$level" :index="index" :paths="item.paths" />
|
|
5
|
+
</template>
|
|
6
|
+
</template>
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { computed } from 'vue';
|
|
9
|
+
import NodeLoader from './NodeLoader.vue';
|
|
10
|
+
|
|
11
|
+
interface NodeProps {
|
|
12
|
+
label?: string | ((data: any) => string);
|
|
13
|
+
field?: string | ((data: any) => string);
|
|
14
|
+
model?: string | ((data: any) => string);
|
|
15
|
+
attrs?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
16
|
+
clear?: boolean | ((data: any) => boolean);
|
|
17
|
+
media?: string | ((data: any) => string);
|
|
18
|
+
value?: any | ((data: any) => any);
|
|
19
|
+
event?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
20
|
+
child?: NodeProps[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Props {
|
|
24
|
+
nodes: NodeProps[];
|
|
25
|
+
level?: number;
|
|
26
|
+
index?: number;
|
|
27
|
+
paths?: string;
|
|
28
|
+
}
|
|
29
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
30
|
+
nodes: () => [],
|
|
31
|
+
level: 0,
|
|
32
|
+
index: 0,
|
|
33
|
+
paths: '',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const $nodes = computed(() => {
|
|
37
|
+
return props.nodes.map((item, index) => {
|
|
38
|
+
const paths = props.paths ? `${props.paths}-${index}` : `${index}`;
|
|
39
|
+
const context = { node: item, level: props.level, index, paths } as const;
|
|
40
|
+
|
|
41
|
+
let attrs: any = item.attrs;
|
|
42
|
+
if (typeof attrs === 'function') {
|
|
43
|
+
try {
|
|
44
|
+
attrs = attrs(context);
|
|
45
|
+
} catch {
|
|
46
|
+
/* noop */
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let value: any = (item as any).value;
|
|
51
|
+
if (typeof value === 'function') {
|
|
52
|
+
try {
|
|
53
|
+
value = value(context);
|
|
54
|
+
} catch {
|
|
55
|
+
/* noop */
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let ev: any = (item as any).event;
|
|
60
|
+
if (typeof ev === 'function') {
|
|
61
|
+
try {
|
|
62
|
+
ev = ev(context);
|
|
63
|
+
} catch {
|
|
64
|
+
ev = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const $events: Record<string, any> = {};
|
|
69
|
+
if (ev && typeof ev === 'object') {
|
|
70
|
+
for (const key in ev) {
|
|
71
|
+
const fn = ev[key];
|
|
72
|
+
if (typeof fn === 'function') {
|
|
73
|
+
$events[key] = (...args: any[]) => fn(context, ...args);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { ...item, index, paths, attrs, value, $events } as any;
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const $level = computed(() => {
|
|
83
|
+
return props.level + 1;
|
|
84
|
+
});
|
|
85
|
+
</script>
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
<div v-for="(item, idx) in node.other.suffix" v-html="item.value" v-bind="item.attrs" :key="idx"></div>
|
|
171
171
|
</div>
|
|
172
172
|
</div>
|
|
173
|
-
<div v-if="$slots.submit" class="full
|
|
173
|
+
<div v-if="$slots.submit" class="w-full" ui-flex="row lm">
|
|
174
174
|
<div class="flex-fixed" :style="labelcss(node)"> </div>
|
|
175
175
|
<div class="flex-block"><slot name="submit"></slot></div>
|
|
176
176
|
</div>
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
<div class="flex-block pr">
|
|
3
3
|
<template v-if="mode === 'view'">
|
|
4
4
|
<slot :name="`${node.field}-value`" :data="data" :node="node" :bind.sync="bind">
|
|
5
|
-
<div class="nt-ss"><div v-html="value" style="padding-top: 2px
|
|
5
|
+
<div class="nt-ss"><div v-html="value" style="padding-top: 2px"></div></div>
|
|
6
6
|
</slot>
|
|
7
7
|
</template>
|
|
8
8
|
<template v-else>
|
|
9
|
-
<el-input v-if="node.model[0] === 'Input'" v-model="value" class="full
|
|
10
|
-
<el-input
|
|
9
|
+
<el-input v-if="node.model[0] === 'Input'" v-model="value" class="w-full" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted" />
|
|
10
|
+
<el-input
|
|
11
|
+
v-if="node.model[0] === 'Textarea'"
|
|
12
|
+
v-model="value"
|
|
13
|
+
class="w-full"
|
|
14
|
+
v-bind="{ ...(node.model[1] || {}, { type: 'textarea', rows: 3 }) }"
|
|
15
|
+
@input="setInteracted"
|
|
16
|
+
@blur="setInteracted"
|
|
17
|
+
/>
|
|
11
18
|
<el-select v-else-if="node.model[0] === 'Select'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted">
|
|
12
19
|
<el-option v-for="item in node.enums" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
|
13
20
|
</el-select>
|
|
@@ -19,17 +26,35 @@
|
|
|
19
26
|
</el-checkbox-group>
|
|
20
27
|
<el-checkbox v-else-if="node.model[0] === 'Checkbox'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted"> </el-checkbox>
|
|
21
28
|
<el-switch v-else-if="node.model[0] === 'Switch'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted"> </el-switch>
|
|
22
|
-
<el-time-select v-else-if="node.model[0] === 'TimeSelect'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted">
|
|
23
|
-
|
|
24
|
-
<el-
|
|
25
|
-
|
|
26
|
-
<el-
|
|
29
|
+
<el-time-select v-else-if="node.model[0] === 'TimeSelect'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted">
|
|
30
|
+
</el-time-select>
|
|
31
|
+
<el-time-picker v-else-if="node.model[0] === 'TimePicker'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted">
|
|
32
|
+
</el-time-picker>
|
|
33
|
+
<el-date-picker v-else-if="node.model[0] === 'DatePicker'" v-model="value" v-bind="{ ...(node.model[1] || {}) }" @input="setInteracted" @blur="setInteracted">
|
|
34
|
+
</el-date-picker>
|
|
35
|
+
<el-date-picker
|
|
36
|
+
v-else-if="node.model[0] === 'DateTimePicker'"
|
|
37
|
+
v-model="value"
|
|
38
|
+
type="datetime"
|
|
39
|
+
v-bind="{ ...(node.model[1] || {}) }"
|
|
40
|
+
@input="setInteracted"
|
|
41
|
+
@blur="setInteracted"
|
|
42
|
+
>
|
|
43
|
+
</el-date-picker>
|
|
44
|
+
<el-cascader
|
|
45
|
+
v-else-if="node.model[0] === 'Cascader'"
|
|
46
|
+
v-model="value"
|
|
47
|
+
:options="node.enums"
|
|
48
|
+
v-bind="{ ...node.model[1] }"
|
|
49
|
+
@input="setInteracted"
|
|
50
|
+
@blur="setInteracted"
|
|
51
|
+
></el-cascader>
|
|
27
52
|
<gallery-value v-else-if="node.model[0] === 'SelectImg'" :form="data" :node="node" v-bind="{ ...node.model[1] }"></gallery-value>
|
|
28
53
|
<!-- 自定义组件插槽 -->
|
|
29
54
|
<slot v-else-if="node.model[0]" :name="node.model[0]" :data="data" :node="node" :bind.sync="bind"></slot>
|
|
30
55
|
<!-- 自定义字段插槽 -->
|
|
31
56
|
<slot v-else :name="`${node.field}-value`" :data="data" :node="node" :bind.sync="bind">
|
|
32
|
-
<div class="nt-ss"><div v-html="value" style="padding-top: 2px
|
|
57
|
+
<div class="nt-ss"><div v-html="value" style="padding-top: 2px"></div></div>
|
|
33
58
|
</slot>
|
|
34
59
|
<p v-show="error.verify === 'no'" class="form-loader-verify" :data-verify-type="error.co">{{ error.tips }}</p>
|
|
35
60
|
</template>
|
|
@@ -44,28 +69,28 @@
|
|
|
44
69
|
props: {
|
|
45
70
|
mode: {
|
|
46
71
|
type: String,
|
|
47
|
-
default: 'edit'
|
|
72
|
+
default: 'edit',
|
|
48
73
|
},
|
|
49
74
|
node: {
|
|
50
75
|
type: Object,
|
|
51
|
-
default: () => ({})
|
|
76
|
+
default: () => ({}),
|
|
52
77
|
},
|
|
53
78
|
data: {
|
|
54
79
|
type: Object,
|
|
55
|
-
default: () => ({})
|
|
80
|
+
default: () => ({}),
|
|
56
81
|
},
|
|
57
82
|
interacted: {
|
|
58
83
|
type: Boolean,
|
|
59
|
-
default: false
|
|
60
|
-
}
|
|
84
|
+
default: false,
|
|
85
|
+
},
|
|
61
86
|
},
|
|
62
87
|
data() {
|
|
63
88
|
return {
|
|
64
89
|
_interacted: false,
|
|
65
90
|
bind: {
|
|
66
|
-
value: null
|
|
91
|
+
value: null,
|
|
67
92
|
},
|
|
68
|
-
error: {}
|
|
93
|
+
error: {},
|
|
69
94
|
};
|
|
70
95
|
},
|
|
71
96
|
created() {},
|
|
@@ -99,8 +124,8 @@
|
|
|
99
124
|
this.$set(this.data, this.node.field, value);
|
|
100
125
|
}
|
|
101
126
|
this.validate();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
127
|
+
},
|
|
128
|
+
},
|
|
104
129
|
},
|
|
105
130
|
methods: {
|
|
106
131
|
async validate() {
|
|
@@ -166,7 +191,7 @@
|
|
|
166
191
|
this.validate();
|
|
167
192
|
}, 50);
|
|
168
193
|
}
|
|
169
|
-
}
|
|
194
|
+
},
|
|
170
195
|
},
|
|
171
196
|
watch: {
|
|
172
197
|
bind: {
|
|
@@ -183,22 +208,22 @@
|
|
|
183
208
|
this.$set(this.data, this.node.field, value);
|
|
184
209
|
this.$set(this.bind, 'value', value);
|
|
185
210
|
},
|
|
186
|
-
deep: true
|
|
211
|
+
deep: true,
|
|
187
212
|
},
|
|
188
213
|
interacted: {
|
|
189
214
|
handler(val) {
|
|
190
215
|
this._interacted = val;
|
|
191
216
|
this.validate();
|
|
192
217
|
},
|
|
193
|
-
deep: true
|
|
218
|
+
deep: true,
|
|
194
219
|
},
|
|
195
220
|
value: {
|
|
196
221
|
handler() {
|
|
197
222
|
this.validate();
|
|
198
223
|
},
|
|
199
|
-
deep: true
|
|
200
|
-
}
|
|
201
|
-
}
|
|
224
|
+
deep: true,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
202
227
|
};
|
|
203
228
|
</script>
|
|
204
229
|
<style>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<script setup lang="ts">
|
|
76
76
|
import { nextTick, reactive, ref, watch, onMounted } from 'vue';
|
|
77
77
|
import LayerLoader from './LayerLoader.vue';
|
|
78
|
-
import { useBasicStore, useWorksStore, storeToRefs } from '@/
|
|
78
|
+
import { useBasicStore, useWorksStore, storeToRefs } from '@/stores';
|
|
79
79
|
import { deepcopy } from '@fekit/utils';
|
|
80
80
|
import scrollto from '@fekit/scrollto';
|
|
81
81
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="full
|
|
2
|
+
<div class="w-full" ui-flex="row xt">
|
|
3
3
|
<div class="flex-block mr-mm-sub my-sm-sub" ui-flex="row lm wrap">
|
|
4
4
|
<template v-for="(item, idx) in state.limit" :key="idx">
|
|
5
5
|
<div v-if="!item._close" ui-flex="row lm" v-bind="{ ...(item.attrs || {}) }">
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
layer: {
|
|
47
47
|
moveing: false,
|
|
48
48
|
from: null,
|
|
49
|
-
correct: ''
|
|
50
|
-
}
|
|
49
|
+
correct: '',
|
|
50
|
+
},
|
|
51
51
|
});
|
|
52
52
|
const word: any = {};
|
|
53
53
|
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
const props: any = withDefaults(defineProps<Props>(), {
|
|
62
62
|
data: () => [],
|
|
63
63
|
path: '',
|
|
64
|
-
line: true
|
|
64
|
+
line: true,
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
// 内部状态
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
top: 1.5em;
|
|
268
268
|
bottom: 0.5em;
|
|
269
269
|
left: 0.6em;
|
|
270
|
-
background-color: var(--co-line-ls);
|
|
270
|
+
background-color: var(--co-line-o-ls);
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
|
|
@@ -388,7 +388,7 @@
|
|
|
388
388
|
}
|
|
389
389
|
|
|
390
390
|
[data-selected='true'] {
|
|
391
|
-
background: var(--co-main-ss) !important;
|
|
391
|
+
background: var(--co-main-o-ss) !important;
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
.fekit-json-tree-tools {
|
|
@@ -451,7 +451,7 @@
|
|
|
451
451
|
left: 0;
|
|
452
452
|
top: 0;
|
|
453
453
|
z-index: 1;
|
|
454
|
-
box-shadow: inset 0 1px 0 0 var(--co-main-ls);
|
|
454
|
+
box-shadow: inset 0 1px 0 0 var(--co-main-o-ls);
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
// &[tree-level='2'] {
|
|
@@ -478,7 +478,7 @@
|
|
|
478
478
|
left: 0;
|
|
479
479
|
top: 0;
|
|
480
480
|
z-index: 1;
|
|
481
|
-
box-shadow: inset 0 0 0 1px var(--co-main-ls);
|
|
481
|
+
box-shadow: inset 0 0 0 1px var(--co-main-o-ls);
|
|
482
482
|
}
|
|
483
483
|
}
|
|
484
484
|
// 插入后面
|
|
@@ -493,7 +493,7 @@
|
|
|
493
493
|
left: 0;
|
|
494
494
|
top: 0;
|
|
495
495
|
z-index: 1;
|
|
496
|
-
box-shadow: inset 0 -1px 0 0 var(--co-main-ls);
|
|
496
|
+
box-shadow: inset 0 -1px 0 0 var(--co-main-o-ls);
|
|
497
497
|
}
|
|
498
498
|
|
|
499
499
|
// &[tree-level='2'] {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
:col-fixed-side="col.fixed || 'l'"
|
|
88
88
|
:data-field="col.field"
|
|
89
89
|
>
|
|
90
|
-
<slot :name="col.field" :col="col" :item="item" :idx="idx"><TableRender :
|
|
90
|
+
<slot :name="col.field" :col="col" :item="item" :idx="idx"><TableRender :node="col" :data="item" /></slot>
|
|
91
91
|
</td>
|
|
92
92
|
</template>
|
|
93
93
|
<td v-if="slots.operate" col-fixed="r" class="ar"><slot name="operate" :item="item" :idx="idx"></slot></td>
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
<tr v-if="!col.__close">
|
|
128
128
|
<td class="nowrap vt n-ss">{{ col.label }}:</td>
|
|
129
129
|
<td class="n-ss">
|
|
130
|
-
<TableRender :
|
|
130
|
+
<TableRender :node="col" :data="item" />
|
|
131
131
|
</td>
|
|
132
132
|
</tr>
|
|
133
133
|
</template>
|
|
@@ -167,14 +167,14 @@
|
|
|
167
167
|
field: string | (() => string);
|
|
168
168
|
width?: string | (() => string);
|
|
169
169
|
fixed?: string | (() => string);
|
|
170
|
-
thead?: object | (() => object);
|
|
171
|
-
tbody?: object | (() => object);
|
|
172
170
|
paths?: string | (() => string);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
171
|
+
thead?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
172
|
+
tbody?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
173
|
+
model?: string | any[] | ((data: any) => string | any[]);
|
|
174
|
+
enums?: any[] | ((data: any) => any[]);
|
|
175
|
+
rules?: any[] | ((data: any) => any[]);
|
|
176
|
+
event?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
177
|
+
attrs?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
178
178
|
value?: any | (() => any);
|
|
179
179
|
clear?: boolean | (() => boolean);
|
|
180
180
|
order?: 0 | 1 | 2 | number | (() => 0 | 1 | 2 | number);
|
|
@@ -268,6 +268,11 @@
|
|
|
268
268
|
state.__last = 0;
|
|
269
269
|
state.table = deepcopy(props.table || [])
|
|
270
270
|
?.map((col: TableColumn, idx: number) => {
|
|
271
|
+
// 标题处理
|
|
272
|
+
if (isFunction(col.label)) {
|
|
273
|
+
col.label = col.label(props.lists);
|
|
274
|
+
}
|
|
275
|
+
|
|
271
276
|
// 表头属性处理
|
|
272
277
|
col.thead ??= {};
|
|
273
278
|
col.thead.class = (col.thead.class || '').split(/\s+/);
|
|
@@ -1,61 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<template v-if="isArray(
|
|
3
|
-
<div
|
|
4
|
-
<TableRender v-for="(sub, idx) in
|
|
2
|
+
<template v-if="isArray(node.child)">
|
|
3
|
+
<div v-bind="attrs" v-on="event" v-memo="[node.child, data]">
|
|
4
|
+
<TableRender v-for="(sub, idx) in node.child" :key="idx" :node="sub" :data="data" />
|
|
5
5
|
</div>
|
|
6
6
|
</template>
|
|
7
|
-
<template v-else-if="
|
|
8
|
-
<IFollowView>
|
|
9
|
-
<TableRender :
|
|
7
|
+
<template v-else-if="node.popup">
|
|
8
|
+
<IFollowView v-memo="[node.popup, data]">
|
|
9
|
+
<TableRender :node="{ ...node, popup: null }" :data="data" />
|
|
10
10
|
<template #tips>
|
|
11
|
-
<TableRender :
|
|
11
|
+
<TableRender :node="isFunction(node.popup) ? node.popup(data) : node.popup" :data="data" />
|
|
12
12
|
</template>
|
|
13
13
|
</IFollowView>
|
|
14
14
|
</template>
|
|
15
15
|
<template v-else>
|
|
16
|
-
<div v-if="
|
|
17
|
-
<
|
|
16
|
+
<div v-if="model.value" v-bind="attrs" v-on="event">
|
|
17
|
+
<div v-if="model.value === 'image'" ui-cover="1:1" v-bind="model.attrs">
|
|
18
|
+
<div class="pa full bg-case-o-ls r-sm ot-no ol-no" :class="state.isloaded ? 'o-no' : 'o-ms'" ui-flex="col cm"><i ui-load="@d"></i></div>
|
|
19
|
+
<img ref="img" class="r-sm" :src="value" @load="state.isloaded = 1" />
|
|
20
|
+
</div>
|
|
21
|
+
<label v-else-if="model.value === 'switch'" ui-form="@a type:switch" @click.prevent>
|
|
22
|
+
<input type="checkbox" :checked="value" />
|
|
23
|
+
<span v-if="model.attrs?.label">{{ model.attrs?.label }}</span>
|
|
24
|
+
</label>
|
|
18
25
|
</div>
|
|
19
|
-
<div v-else
|
|
26
|
+
<div v-else v-bind="attrs" v-on="event" v-html="value"></div>
|
|
20
27
|
</template>
|
|
21
28
|
</template>
|
|
22
29
|
<script lang="ts" setup>
|
|
23
|
-
import { computed } from 'vue';
|
|
24
|
-
import { isFunction, isArray, isObject,
|
|
30
|
+
import { computed, onMounted, reactive, ref } from 'vue';
|
|
31
|
+
import { isFunction, isArray, isObject, isString, findEnumName } from '@fekit/utils';
|
|
25
32
|
import { useRoute, useRouter } from 'vue-router';
|
|
26
33
|
import TableRender from './TableRender.vue';
|
|
27
34
|
import { IFollowView } from '../../basic';
|
|
28
35
|
|
|
29
|
-
const DefaultImage =
|
|
30
|
-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKYAAACmBAMAAACipulEAAAAHlBMVEXMzMz////z8/Pf39/Z2dnS0tLq6urk5OTu7u74+PjCLuPVAAABxUlEQVRo3u2YsUsDMRSHX9Wzupn22qObVxAd7SCuV1BwvGrVtQcqjlYQHFVEVzv575qklReE9urlFTL8vqUvQz+Se3m5yyMAAAAAAAAAAAAAsFIu7rvz+DiqprxSi7itotxQi8kqOHslzqbHNAUnul3q/PJYutzi01Jn47/KSBm+jxep8yopSojqgklaV5qRDor5zsMKTru4gazTJmEtfKcyQU3Waf/UE3bGXPb7p5fDRwmnuhkWyvJEhmt/JzOiKZtyzph+6Us5O1zY0UTI2TKy5+4nl5W/M9PpT00NmEDG2dbDgiMR5w7R1ix84brycz7oyfGU6yLO3HmIGUUSzoY9m3jxqYAzsRuIt9VYwBm7Z1OTB57Owt1XfQFn649zEOg8YzctiYyz6Wpizxzxcmtunb5K1JGtR65TkdrMiCazsMOHnZ9zlx9ozHXq5XTfyBnr/ZwdPTy30Z6OJr5OfhOf6d934tPZ15mQJjrJSVN4O3mi/NEg5GzkNCVKBZy8estYeTuZdmbuDYWScDIHd29KSTmZEJ26GsUvxpEqJw/gDrvMXTuInsASvYsgeizlvaBAelZlvTUAAAAAAAAAAAAAsEp+AEDOpCBEwOONAAAAAElFTkSuQmCC';
|
|
31
|
-
|
|
32
|
-
// 通过枚举值查找枚举名
|
|
33
|
-
const findEnumName = (enums: any, val: any, join: boolean | string = ' Ι ') => {
|
|
34
|
-
// 转换核心
|
|
35
|
-
const _core = (v: any) => {
|
|
36
|
-
const { label = v }: any = enums.find(({ value = '' }: any) => value == v) || {};
|
|
37
|
-
return label;
|
|
38
|
-
};
|
|
39
|
-
// 判断枚举字典是否可用
|
|
40
|
-
if (enums && enums.find) {
|
|
41
|
-
// 兼容多种入参类型
|
|
42
|
-
if (isArray(val)) {
|
|
43
|
-
// 数组
|
|
44
|
-
const arr = val.map((i: any) => _core(i));
|
|
45
|
-
return join ? arr.join(join) : arr;
|
|
46
|
-
} else {
|
|
47
|
-
return _core(val);
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
return val;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
36
|
const route = useRoute();
|
|
55
37
|
const router = useRouter();
|
|
56
38
|
|
|
57
39
|
const props: any = defineProps({
|
|
58
|
-
|
|
40
|
+
node: {
|
|
59
41
|
type: Object,
|
|
60
42
|
default: () => ({}),
|
|
61
43
|
},
|
|
@@ -65,47 +47,95 @@
|
|
|
65
47
|
},
|
|
66
48
|
});
|
|
67
49
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
const img = ref<HTMLImageElement | null>(null);
|
|
51
|
+
onMounted(() => {
|
|
52
|
+
if (img.value) {
|
|
53
|
+
state.isloaded = img.value.complete && img.value.naturalWidth > 0 ? 1 : 0;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const state: any = reactive({
|
|
58
|
+
isloaded: 0,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// 属性处理
|
|
62
|
+
const attrs = computed(() => {
|
|
63
|
+
const a = props.node.attrs;
|
|
64
|
+
let attrs = isFunction(a) ? a?.(props.data) : a;
|
|
65
|
+
|
|
66
|
+
// 确保 attrs 存在
|
|
67
|
+
if (!attrs) attrs = {};
|
|
68
|
+
else attrs = { ...attrs };
|
|
69
|
+
|
|
70
|
+
// 处理 class 属性
|
|
71
|
+
if (attrs.class) {
|
|
72
|
+
attrs.class = attrs.class.split(/\s+/);
|
|
73
|
+
if (!attrs.class.some((c: string) => c === 'wrap' || c === 'nowrap')) {
|
|
74
|
+
attrs.class.push('nowrap');
|
|
77
75
|
}
|
|
78
|
-
} else
|
|
79
|
-
|
|
76
|
+
} else {
|
|
77
|
+
attrs.class = ['nowrap'];
|
|
80
78
|
}
|
|
81
|
-
return obj;
|
|
82
|
-
};
|
|
83
79
|
|
|
84
|
-
|
|
80
|
+
return attrs;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// 模型处理
|
|
84
|
+
const model: any = computed(() => {
|
|
85
|
+
const m = props.node.model;
|
|
86
|
+
if (!m) return { value: '', attrs: {} };
|
|
87
|
+
|
|
88
|
+
const model = isFunction(m) ? m(props.data) : m;
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
let value = '';
|
|
91
|
+
let attrs = {};
|
|
92
|
+
if (isString(model)) {
|
|
93
|
+
value = model;
|
|
94
|
+
} else if (isArray(model)) {
|
|
95
|
+
value = model[0] ?? '';
|
|
96
|
+
attrs = isObject(model[1]) ? model[1] : {};
|
|
97
|
+
}
|
|
98
|
+
value = value.toString().toLowerCase();
|
|
99
|
+
|
|
100
|
+
return { value, attrs };
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 枚举处理
|
|
104
|
+
const enums = computed(() => {
|
|
105
|
+
const e = props.node.enums;
|
|
106
|
+
return isFunction(e) ? e(props.data) : e;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// 数值处理
|
|
110
|
+
const value = computed(() => {
|
|
111
|
+
const n = props?.node;
|
|
112
|
+
const v = props?.data?.[n.field];
|
|
113
|
+
return n?.value !== null && n?.value !== undefined
|
|
114
|
+
? isFunction(n?.value)
|
|
115
|
+
? n?.value(props?.data)
|
|
116
|
+
: n?.value
|
|
117
|
+
: findEnumName(enums.value, v) !== null && findEnumName(enums.value, v) !== undefined
|
|
118
|
+
? findEnumName(enums.value, v)
|
|
93
119
|
: '‐‐';
|
|
94
|
-
};
|
|
120
|
+
});
|
|
95
121
|
|
|
96
|
-
// 事件处理
|
|
97
|
-
const event
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
122
|
+
// 事件处理 (直接使用 computed)
|
|
123
|
+
const event = computed(() => {
|
|
124
|
+
let e = props.node.event;
|
|
125
|
+
if (isFunction(e)) {
|
|
126
|
+
e = e(props.data);
|
|
127
|
+
}
|
|
128
|
+
const events: any = {};
|
|
129
|
+
if (isObject(e)) {
|
|
130
|
+
for (const key in e) {
|
|
131
|
+
const fun = e[key];
|
|
102
132
|
if (isFunction(fun)) {
|
|
103
|
-
|
|
104
|
-
return fun({ data, route, router }, ...args);
|
|
133
|
+
events[key] = (...args: any) => {
|
|
134
|
+
return fun({ data: props.data, route, router }, ...args);
|
|
105
135
|
};
|
|
106
136
|
}
|
|
107
137
|
}
|
|
108
138
|
}
|
|
109
|
-
return
|
|
110
|
-
};
|
|
139
|
+
return events;
|
|
140
|
+
});
|
|
111
141
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div ui-pagination="@a" class="full
|
|
2
|
+
<div ui-pagination="@a" class="w-full pading" ui-flex="row rm">
|
|
3
3
|
<div class="ml-sl ar mob-ac" ui-flex="row rm">
|
|
4
4
|
<div class="mx-ss-sub" ui-flex="row">
|
|
5
5
|
<div v-if="state.showTotal" ui-flex="row cm" ui-hide="<pad">共 {{ data[defined.total || 'total'] || 0 }} 条</div>
|
package/tsconfig.json
CHANGED
|
@@ -19,6 +19,6 @@
|
|
|
19
19
|
},
|
|
20
20
|
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
|
|
21
21
|
},
|
|
22
|
-
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/shims-vue.d.ts"],
|
|
22
|
+
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/shims-vue.d.ts", "src/components/loader/FormLoader/FormRender@v3.vue.backup", "src/components/loader/FormLoader/FormLoader@v3.vue.backup"],
|
|
23
23
|
"exclude": ["node_modules"]
|
|
24
24
|
}
|