@neatui/vue 3.0.0 → 4.0.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/README.md +1 -10
- package/package.json +5 -2
- package/rollup.config.js +42 -2
- package/src/components/basic/IDraggable@b.vue +1 -1
- package/src/components/basic/IFollowView.vue +2 -2
- package/src/components/basic/IScrollView.vue +441 -45
- package/src/components/basic/LayerView/Layer.vue +193 -42
- package/src/components/display/Calendar.vue +6 -6
- package/src/components/display/CalendarReg.vue +6 -6
- package/src/components/display/PhotoEditor.vue +2 -2
- package/src/components/display/TreeView.vue +4 -3
- package/src/components/form/Cascader.vue +3 -3
- package/src/components/form/DatePicker.vue +2 -2
- package/src/components/form/{DateRangePicker@v3.vue → DateRangePicker.vue} +2 -1
- package/src/components/form/{DateRangeView@v3.vue → DateRangeView.vue} +11 -11
- package/src/components/form/DateView.vue +461 -82
- package/src/components/form/ImgUpload.vue +3 -3
- package/src/components/form/{MoreSelect@v3.vue → MoreSelect.vue} +1 -1
- package/src/components/form/MoreSelectList.vue +1 -1
- package/src/components/form/{MoreSelectPanel@v3.vue → MoreSelectPanel.vue} +1 -1
- package/src/components/form/MoreSelectPicker.vue +3 -3
- package/src/components/form/MoreSelectTags.vue +1 -1
- package/src/components/form/PageMoreSelect.vue +1 -1
- package/src/components/form/PageSelect.vue +1 -1
- package/src/components/form/SearchMoreSelect.vue +1 -1
- package/src/components/form/{SearchSelect@v3.vue → SearchSelect.vue} +1 -1
- package/src/components/form/{Select@v3.vue → Select.vue} +1 -1
- package/src/components/form/SelectList.vue +1 -1
- package/src/components/form/SelectPicker.vue +3 -3
- package/src/components/form/SelectTree/{SelectTree@v1.vue → SelectTree.vue} +1 -1
- package/src/components/form/Switch.vue +2 -1
- package/src/components/form/TimeView.vue +6 -6
- package/src/components/form/Upload.vue +22 -11
- package/src/components/form/index.ts +8 -8
- package/src/components/loader/FormLoader/FormLoader.vue +124 -103
- package/src/components/loader/LayerLoader/LayerLoader.vue +6 -7
- package/src/components/loader/LimitLoader/{LimitLoader@v3.vue → LimitLoader.vue} +4 -4
- package/src/components/loader/LimitLoader/index.ts +1 -1
- package/src/components/loader/TableLoader/TableLoader.vue +7 -7
- package/src/components/loader/TableLoader/TableRender.vue +0 -1
- package/src/components/loader/ViewLoader/{ViewLoader@v1.vue → ViewLoader.vue} +124 -103
- package/src/components/loader/ViewLoader/index.ts +1 -1
- package/src/components/tools/FormDraftsView.vue +4 -4
- package/src/components/tools/FormVerifyView.vue +2 -2
- package/src/components/tools/MoreTools.vue +5 -5
- package/src/components/tools/Pagination@a.vue +4 -4
- package/src/components/tools/Pagination@b.vue +4 -4
- package/tsconfig.json +1 -2
- package/src/components/form/DateView@v2.vue +0 -386
- package/src/components/form/DateView@v3.vue +0 -608
- package/src/components/tools/MoreTools@v2.vue +0 -74
- /package/src/components/form/{Input@v3.vue → Input.vue} +0 -0
- /package/src/components/form/{TextArea.vue → Textarea.vue} +0 -0
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
<template v-if="(!multiple && files && files.length === 0) || (multiple && (!limit || (limit && files && files.length < limit)))">
|
|
13
13
|
<slot>
|
|
14
|
-
<div ui-flex="row cm" ui-form="@a type:upload tips:hover" :class="`upload bg-fore b-solid
|
|
14
|
+
<div ui-flex="row cm" ui-form="@a type:upload tips:hover" :class="`upload bg-fore b-solid b-case b-xs mb-sl ${uploadClass}`" :style="uploadStyle">
|
|
15
15
|
<div v-if="tips" ui-form-tips>
|
|
16
16
|
{{ tips }}
|
|
17
17
|
</div>
|
|
18
18
|
<input v-if="!crop" type="file" class="pa input" :multiple="multiple" @change="change" />
|
|
19
19
|
<div v-else class="input pa" @click="uploadClick"></div>
|
|
20
20
|
<div class="co-note ac input-icon">
|
|
21
|
-
<i class="icon icon-upload fs-
|
|
22
|
-
<div class="fs-
|
|
21
|
+
<i class="icon icon-upload fs-ml"></i>
|
|
22
|
+
<div class="fs-sm">上传图片</div>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
</slot>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<li
|
|
5
5
|
v-for="(item, idx) of props.options"
|
|
6
6
|
:key="idx"
|
|
7
|
-
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss
|
|
7
|
+
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss b-main-o-ml' : 'b-case'}`"
|
|
8
8
|
class="n-sm r-ss b-solid b-xs"
|
|
9
9
|
@click.stop="select(item.value)"
|
|
10
10
|
>
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
</Input>
|
|
7
7
|
<template #options>
|
|
8
8
|
<div class="full n-xs" ui-flex="col xy">
|
|
9
|
-
<div class="flex-fixed n-ms b-solid
|
|
9
|
+
<div class="flex-fixed n-ms b-solid b-line bb-xs" ui-flex="row xm">
|
|
10
10
|
<div><button class="co-note" @click="cancel">取消</button></div>
|
|
11
11
|
<div><button class="co-main" @click="confirm">确定</button></div>
|
|
12
12
|
</div>
|
|
13
13
|
<div class="flex-block">
|
|
14
14
|
<IScrollView class="full n-ms" :pull="false" :load="false">
|
|
15
15
|
<ul v-if="props.options?.length" class="my-sm-sub">
|
|
16
|
-
<li class="ux-hover n-sm r-ss nowrap b-solid
|
|
16
|
+
<li class="ux-hover n-sm r-ss nowrap b-solid b-case b-xs" v-for="(item, idx) of props.options" :key="idx" @click.stop="select(item.value)">
|
|
17
17
|
<label style="pointer-events: none" ui-form="@a type:checkbox :block">
|
|
18
18
|
<input type="checkbox" :name="field" :checked="mv?.some((i: any) => `${i}` === `${item.value}`)" />
|
|
19
19
|
<span class="ml-sm">{{ item.label || item }}</span>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
<script setup lang="ts">
|
|
32
32
|
import { reactive, ref, computed, watch } from 'vue';
|
|
33
|
-
import
|
|
33
|
+
import Input from './Input.vue';
|
|
34
34
|
import { IPickerView, IScrollView } from '../basic';
|
|
35
35
|
const ipicker: any = ref(null);
|
|
36
36
|
const emits = defineEmits(['update:modelValue']);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<li
|
|
6
6
|
v-for="(item, idx) of props.options"
|
|
7
7
|
:key="idx"
|
|
8
|
-
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss
|
|
8
|
+
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss b-main-o-ml' : 'b-case'}`"
|
|
9
9
|
class="nx-ms ny-ss r-sm b-solid b-xs pr"
|
|
10
10
|
@click.stop="select(item.value)"
|
|
11
11
|
>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
<script setup lang="ts">
|
|
50
50
|
import { reactive, ref, computed } from 'vue';
|
|
51
|
-
import
|
|
51
|
+
import Input from './Input.vue';
|
|
52
52
|
import { IFollowView } from '../basic';
|
|
53
53
|
const ifollow: any = ref(null);
|
|
54
54
|
console.warn('「SearchSelect」 即将废弃,建议使用「Select」 设置参数search为true,示例:<Select v-model="value" :search="true" />');
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
|
|
67
67
|
<script setup lang="ts">
|
|
68
68
|
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
|
69
|
-
import
|
|
69
|
+
import Input from './Input.vue';
|
|
70
70
|
import { IFollowView } from '../basic';
|
|
71
71
|
const ifollow: any = ref(null);
|
|
72
72
|
const customInputRef: any = ref(null);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<ul v-if="props.options?.length" class="my-sm-sub lh-ss">
|
|
3
3
|
<li
|
|
4
4
|
class="hover:bg-main-o-ss n-sl r-ss b-solid b-xs"
|
|
5
|
-
:class="`${item.value === mv ? '
|
|
5
|
+
:class="`${item.value === mv ? 'b-main-o-ml bg-main-o-ss' : 'b-case'}`"
|
|
6
6
|
v-for="(item, idx) of props.options"
|
|
7
7
|
:key="idx"
|
|
8
8
|
@click="mv = item.value === mv ? '' : item.value"
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
</Input>
|
|
7
7
|
<template #options>
|
|
8
8
|
<div class="full n-xs" ui-flex="col xy">
|
|
9
|
-
<div class="flex-fixed n-ms b-solid
|
|
9
|
+
<div class="flex-fixed n-ms b-solid b-line bb-xs" ui-flex="row xm">
|
|
10
10
|
<div><button class="co-note" @click="cancel">取消</button></div>
|
|
11
11
|
<div><button class="co-main" @click="select">确定</button></div>
|
|
12
12
|
</div>
|
|
13
13
|
<div class="flex-block">
|
|
14
14
|
<IScrollView class="full n-ms" :pull="false" :load="false">
|
|
15
15
|
<ul v-if="props.options?.length" class="my-sm-sub">
|
|
16
|
-
<li class="ux-hover n-sm r-ss b-solid
|
|
16
|
+
<li class="ux-hover n-sm r-ss b-solid b-case b-xs" v-for="(item, idx) of props.options" :key="idx" @click="mv = item.value">
|
|
17
17
|
<label ui-form="@a type:radio">
|
|
18
18
|
<input type="radio" :name="item.field" :checked="item.value === mv" /><span>{{ item.label || item }}</span>
|
|
19
19
|
</label>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
<script setup lang="ts">
|
|
31
31
|
import { reactive, ref, computed } from 'vue';
|
|
32
|
-
import
|
|
32
|
+
import Input from './Input.vue';
|
|
33
33
|
import { IPickerView, IScrollView } from '../basic';
|
|
34
34
|
import { watch } from 'vue';
|
|
35
35
|
const ipicker: any = ref(null);
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
42
|
import { reactive, ref, computed, watch } from 'vue';
|
|
43
|
-
import
|
|
43
|
+
import Input from '../Input.vue';
|
|
44
44
|
import { IFollowView } from '../../basic';
|
|
45
45
|
import { TreeView } from '../../display';
|
|
46
46
|
import { findByJson, filterJson } from '@fekit/utils';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="`${frame ? 'b-solid
|
|
3
|
-
<div ui-calendar-head="" class="nx-sl ny-sm b-solid
|
|
2
|
+
<div :class="`${frame ? 'b-solid b-line b-xs r-sm' : ''}`" ui-flex="col xy">
|
|
3
|
+
<div ui-calendar-head="" class="nx-sl ny-sm b-solid b-line bb-xs">
|
|
4
4
|
<div ui-flex="row lm"></div>
|
|
5
5
|
<div ui-flex="row cm" class="nx-ss-sub">
|
|
6
6
|
<p class="mx-ss-sub">
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
<div ui-flex="row rm"></div>
|
|
13
13
|
</div>
|
|
14
|
-
<div ui-flex="row am" class="fs-
|
|
14
|
+
<div ui-flex="row am" class="fs-ss bold nx-sl nt-sm"><span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span></div>
|
|
15
15
|
<div>
|
|
16
16
|
<ul ui-calendar-days="" ui-flex="row lm" class="flex-wrap nx-sm">
|
|
17
17
|
<li class="ew7 n-sm ux-none" v-for="(item, idx) in curr.days" :key="idx">
|
|
18
18
|
<div v-if="item.day" @click="change(item)" ui-cover="-xs">
|
|
19
19
|
<div
|
|
20
20
|
ui-flex="col cm"
|
|
21
|
-
class="r-sm b-solid
|
|
22
|
-
:class="`${item.isToday ? '
|
|
21
|
+
class="r-sm b-solid b-none b-xs"
|
|
22
|
+
:class="`${item.isToday ? 'b-main-o-ls' : item.isLastMonth || item.isNextMonth ? 'co-note' : item.isHoliday ? 'co-risk' : ''} ${
|
|
23
23
|
state.selected && state.selected === item.date ? 'active bg-main-o-ls co-fore' : 'hover-bg-weak'
|
|
24
24
|
}`"
|
|
25
25
|
>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
56
|
<div ui-flex="row cm" class="nx-ss-sub">
|
|
57
|
-
<ul class="fs-
|
|
57
|
+
<ul class="fs-ss n-sm-sub" ui-flex="row lm">
|
|
58
58
|
<li ui-btn="@a s none">年</li>
|
|
59
59
|
<li ui-btn="@a s none">月</li>
|
|
60
60
|
<li ui-btn="@a s none">日</li>
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<div ui-flex="row lm :wrap" class="neatui-upload mb-sm-sub mr-sm-sub" v-bind="{ ...attrs }">
|
|
3
3
|
<div v-for="(file, idx) in state.files" :key="idx" ui-flex="col cm" class="flex-fixed pr" :style="`width: ${isNumber(width) ? width + 'em' : width}`" v-bind="itemAttrs">
|
|
4
4
|
<div class="w-full pr" :style="`box-sizing: content-box; padding-top: ${ratio}%`">
|
|
5
|
-
<div class="pa full ot-no ol-no bg-fore n-sm b-solid
|
|
5
|
+
<div class="pa full ot-no ol-no bg-fore n-sm b-solid b-case b-xs r-sm" ui-flex="col cm">
|
|
6
6
|
<!-- 删除按钮 -->
|
|
7
|
-
<div class="pa w-
|
|
7
|
+
<div v-if="!disabled" class="pa w-sl h-sl ot-ss or-ss bg-fore co-risk lh-xs r-xl parent-hover:show z-ls" ui-flex="row cm" @click="remove(idx)">
|
|
8
8
|
<svg class="block" style="width: 1.2em; height: 1.2em" viewBox="0 0 1024 1024">
|
|
9
9
|
<path
|
|
10
10
|
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66 0.3L512 563.4l-99.3 118.4-66.1-0.3c-4.4 0-8-3.5-8-8 0-1.9 0.7-3.7 1.9-5.2l130.1-155L340.5 359c-1.2-1.5-1.9-3.3-1.9-5.2 0-4.4 3.6-8 8-8l66.1 0.3L512 464.6l99.3-118.4 66-0.3c4.4 0 8 3.5 8 8 0 1.9-0.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<img v-if="file.type === 'image'" class="r-ss" :src="getImageUrl(file)" alt="" />
|
|
18
18
|
<video v-else-if="file.type === 'video'" class="full r-ss" :src="getImageUrl(file)" controls muted></video>
|
|
19
19
|
<template v-else-if="file.type === 'pdf'">
|
|
20
|
-
<svg t="1705645350800" class="w-
|
|
20
|
+
<svg t="1705645350800" class="w-ls h-ls" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1913">
|
|
21
21
|
<path
|
|
22
22
|
d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z"
|
|
23
23
|
fill="#B7B7BD"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
</svg>
|
|
39
39
|
</template>
|
|
40
40
|
<template v-else-if="file.type === 'xlsx'">
|
|
41
|
-
<svg t="1705645380770" class="w-
|
|
41
|
+
<svg t="1705645380770" class="w-ls h-ls" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2060">
|
|
42
42
|
<path
|
|
43
43
|
d="M205.799024 64.936585H664.850732l231.773658 231.773659v638.376585c0 13.79353-11.18208 24.97561-24.97561 24.97561H205.799024c-13.79353 0-24.97561-11.18208-24.975609-24.97561V89.912195c0-13.79353 11.18208-24.97561 24.975609-24.97561z m448.70681 24.97561H205.799024v845.174634H871.64878V307.055141L654.505834 89.912195z"
|
|
44
44
|
fill="#B7B7BD"
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
</svg>
|
|
88
88
|
</template>
|
|
89
89
|
<template v-else-if="file.type === 'docx'">
|
|
90
|
-
<svg t="1705645401993" class="w-
|
|
90
|
+
<svg t="1705645401993" class="w-ls h-ls" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2207">
|
|
91
91
|
<path
|
|
92
92
|
d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z"
|
|
93
93
|
fill="#B7B7BD"
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
</svg>
|
|
109
109
|
</template>
|
|
110
110
|
<template v-else-if="file.type === 'pptx'">
|
|
111
|
-
<svg t="1705645414803" class="w-
|
|
111
|
+
<svg t="1705645414803" class="w-ls h-ls" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2354">
|
|
112
112
|
<path
|
|
113
113
|
d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z"
|
|
114
114
|
fill="#B7B7BD"
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
</svg>
|
|
130
130
|
</template>
|
|
131
131
|
<template v-else>
|
|
132
|
-
<svg t="1705645436666" class="w-
|
|
132
|
+
<svg t="1705645436666" class="w-ls h-ls" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2501">
|
|
133
133
|
<path
|
|
134
134
|
d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z"
|
|
135
135
|
fill="#B7B7BD"
|
|
@@ -160,14 +160,20 @@
|
|
|
160
160
|
|
|
161
161
|
<!-- 上传按钮 -->
|
|
162
162
|
<template v-if="showUploadButton">
|
|
163
|
-
<slot name="btn">
|
|
164
|
-
<label
|
|
163
|
+
<slot name="btn" :disabled="disabled">
|
|
164
|
+
<label
|
|
165
|
+
class="pr flex-block"
|
|
166
|
+
:class="{ 'ux-disable': disabled }"
|
|
167
|
+
ui-form="@a type:upload tips:hover"
|
|
168
|
+
:style="`width: ${isNumber(width) ? width + 'em' : width}`"
|
|
169
|
+
v-bind="itemAttrs"
|
|
170
|
+
>
|
|
165
171
|
<div class="w-full pr" :style="`box-sizing: content-box; padding-top: ${ratio}%`">
|
|
166
|
-
<div ui-flex="row cm" :class="`pa ot-no ol-no full upload n-sl bg-fore b-solid
|
|
172
|
+
<div ui-flex="row cm" :class="`pa ot-no ol-no full upload n-sl bg-fore b-solid b-case b-xs r-sm ${uploadClass}`" :style="uploadStyle">
|
|
167
173
|
<div v-if="tips" ui-form-tips>
|
|
168
174
|
{{ tips }}
|
|
169
175
|
</div>
|
|
170
|
-
<input style="display: none" type="file" class="pa input" :multiple="!max || max > 1" :accept="accept" @change="change" />
|
|
176
|
+
<input style="display: none" type="file" class="pa input" :multiple="!max || max > 1" :accept="accept" :disabled="disabled" @change="change" />
|
|
171
177
|
<div class="co-note ac input-icon">
|
|
172
178
|
<svg t="1705642180833" style="width: 1em; height: 1em" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4215">
|
|
173
179
|
<path
|
|
@@ -392,6 +398,7 @@
|
|
|
392
398
|
|
|
393
399
|
// 删除文件函数
|
|
394
400
|
const remove = (index: number) => {
|
|
401
|
+
if (props.disabled) return;
|
|
395
402
|
removeFile(index, false);
|
|
396
403
|
};
|
|
397
404
|
|
|
@@ -450,6 +457,10 @@
|
|
|
450
457
|
// 文件上传处理
|
|
451
458
|
const change = (e: Event) => {
|
|
452
459
|
const target = e.target as HTMLInputElement;
|
|
460
|
+
if (props.disabled) {
|
|
461
|
+
target.value = '';
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
453
464
|
const selectedFiles = target.files || [];
|
|
454
465
|
|
|
455
466
|
// 检查文件数量限制
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Input from './Input
|
|
1
|
+
import Input from './Input.vue';
|
|
2
2
|
import InputRange from './InputRange.vue';
|
|
3
3
|
import Switch from './Switch.vue';
|
|
4
4
|
import Textarea from './Textarea.vue';
|
|
@@ -6,24 +6,24 @@ import Textarea from './Textarea.vue';
|
|
|
6
6
|
import Checkbox from './Checkbox.vue';
|
|
7
7
|
import CheckboxItem from './CheckboxItem.vue';
|
|
8
8
|
import CheckboxGroup from './CheckboxGroup.vue';
|
|
9
|
-
import Select from './Select
|
|
9
|
+
import Select from './Select.vue';
|
|
10
10
|
import SelectList from './SelectList.vue';
|
|
11
11
|
import SelectTags from './SelectTags.vue';
|
|
12
12
|
import SelectPicker from './SelectPicker.vue';
|
|
13
|
-
import SearchSelect from './SearchSelect
|
|
14
|
-
import MoreSelect from './MoreSelect
|
|
13
|
+
import SearchSelect from './SearchSelect.vue';
|
|
14
|
+
import MoreSelect from './MoreSelect.vue';
|
|
15
15
|
import MoreSelectList from './MoreSelectList.vue';
|
|
16
16
|
import MoreSelectTags from './MoreSelectTags.vue';
|
|
17
17
|
import MoreSelectPicker from './MoreSelectPicker.vue';
|
|
18
18
|
import SearchMoreSelect from './SearchMoreSelect.vue';
|
|
19
19
|
import PageSelect from './PageSelect.vue';
|
|
20
|
-
import SelectTree from './SelectTree/SelectTree
|
|
20
|
+
import SelectTree from './SelectTree/SelectTree.vue';
|
|
21
21
|
|
|
22
|
-
import DateView from './DateView
|
|
23
|
-
import DateRangeView from './DateRangeView
|
|
22
|
+
import DateView from './DateView.vue';
|
|
23
|
+
import DateRangeView from './DateRangeView.vue';
|
|
24
24
|
import DatePicker from './DatePicker.vue';
|
|
25
25
|
import TimePicker from './TimePicker.vue';
|
|
26
|
-
import DateRangePicker from './DateRangePicker
|
|
26
|
+
import DateRangePicker from './DateRangePicker.vue';
|
|
27
27
|
import ImgUpload from './ImgUpload.vue';
|
|
28
28
|
import Upload from './Upload.vue';
|
|
29
29
|
import Cascader from './Cascader.vue';
|
|
@@ -300,123 +300,146 @@
|
|
|
300
300
|
_lw: 6,
|
|
301
301
|
});
|
|
302
302
|
|
|
303
|
-
//
|
|
304
|
-
const unwatchs:
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
303
|
+
// 结构变化时重建字段监听;普通字段变化只触发对应的联动任务
|
|
304
|
+
const unwatchs: Array<() => void> = [];
|
|
305
|
+
let fieldWatcherGeneration = 0;
|
|
306
|
+
const clearFieldWatchers = () => {
|
|
307
|
+
fieldWatcherGeneration += 1;
|
|
308
|
+
unwatchs.splice(0).forEach((unwatch) => {
|
|
309
|
+
unwatch();
|
|
310
|
+
});
|
|
311
|
+
return fieldWatcherGeneration;
|
|
312
|
+
};
|
|
313
|
+
const rebuildFieldWatchers = (form: any = []) => {
|
|
314
|
+
const generation = clearFieldWatchers();
|
|
315
|
+
const watched: any[] = [];
|
|
316
|
+
const onces: any[] = [];
|
|
317
|
+
const taskRuns = new Map<any, number>();
|
|
318
|
+
state.form = deepcopy(form)?.map((item: any = {}, idx: number) => {
|
|
319
|
+
// 计算Label宽度
|
|
320
|
+
const _w = clw(item.label) + 2;
|
|
321
|
+
if (_w > state._lw) {
|
|
322
|
+
state._lw = _w;
|
|
323
|
+
}
|
|
316
324
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
if (!isArray(val.watch)) {
|
|
328
|
-
val.watch = deepcopy(form).map(({ field = '' }: any = {}) => field);
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
val = { value: val, setup: item[key], watch: deepcopy(form).map(({ field = '' }: any = {}) => field) };
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
// 对象处理
|
|
325
|
+
if (isObject(item)) {
|
|
326
|
+
for (const key in item) {
|
|
327
|
+
let val = item[key] || {};
|
|
328
|
+
let hasInitialResult = false;
|
|
329
|
+
let initialResult: any;
|
|
330
|
+
// 处理函数
|
|
331
|
+
if (isFunction(val)) {
|
|
332
|
+
const setup = val;
|
|
333
|
+
val = setup(deepcopy(props.data), props.form, route, router);
|
|
335
334
|
if (isObject(val)) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
wkeys[k].push({ idx, key, value, setup });
|
|
342
|
-
} else {
|
|
343
|
-
wkeys[k] = [{ idx, key, value, setup }];
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
} else {
|
|
347
|
-
onces.push({ idx, key, value, setup });
|
|
335
|
+
if (!isFunction(val.setup)) {
|
|
336
|
+
val.setup = setup;
|
|
337
|
+
}
|
|
338
|
+
if (!isArray(val.watch)) {
|
|
339
|
+
val.watch = deepcopy(form).map(({ field = '' }: any = {}) => field);
|
|
348
340
|
}
|
|
349
|
-
item[key] = value;
|
|
350
341
|
} else {
|
|
351
|
-
|
|
342
|
+
hasInitialResult = true;
|
|
343
|
+
initialResult = val;
|
|
344
|
+
val = { value: val, setup, watch: deepcopy(form).map(({ field = '' }: any = {}) => field) };
|
|
352
345
|
}
|
|
353
346
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
347
|
+
// 对象处理
|
|
348
|
+
if (isObject(val)) {
|
|
349
|
+
const { value = null, setup = () => {}, watch: _watch = [] } = val || {};
|
|
350
|
+
const task = { idx, key, value, setup, watch: _watch, hasInitialResult, initialResult };
|
|
351
|
+
// 监听字段为空
|
|
352
|
+
if (_watch.length) {
|
|
353
|
+
watched.push(task);
|
|
354
|
+
} else {
|
|
355
|
+
onces.push(task);
|
|
356
|
+
}
|
|
357
|
+
item[key] = value;
|
|
358
|
+
} else {
|
|
359
|
+
item[key] = val;
|
|
360
360
|
}
|
|
361
|
-
} else {
|
|
362
|
-
item.model = ['', { verify: false }];
|
|
363
361
|
}
|
|
364
|
-
|
|
365
|
-
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// 模型处理
|
|
365
|
+
if (item.model) {
|
|
366
|
+
if (isString(item.model)) {
|
|
367
|
+
item.model = [item.model, { verify: false }];
|
|
366
368
|
}
|
|
369
|
+
} else {
|
|
370
|
+
item.model = ['', { verify: false }];
|
|
371
|
+
}
|
|
372
|
+
if (item.model[1] && !Object.prototype.hasOwnProperty.call(item.model[1], 'verify')) {
|
|
373
|
+
item.model[1].verify = false;
|
|
374
|
+
}
|
|
367
375
|
|
|
368
|
-
|
|
369
|
-
|
|
376
|
+
// 添加ID
|
|
377
|
+
item._fid = `form-${props.idx !== '' ? props.idx + '-' : ''}field-${item.field}`;
|
|
370
378
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
return item;
|
|
379
|
-
});
|
|
380
|
-
const runsetup = (item: any = {}) => {
|
|
381
|
-
const { idx = null, key = null, value = null, setup = null }: any = item || {};
|
|
382
|
-
if (state.form[idx] && isFunction(setup)) {
|
|
383
|
-
const v = setup(deepcopy(props.data), state.form[idx], route, router);
|
|
384
|
-
nextTick(() => {
|
|
385
|
-
if (v instanceof Promise) {
|
|
386
|
-
state.form[idx][key] = value;
|
|
387
|
-
v.then((res: any) => {
|
|
388
|
-
state.form[idx][key] = res;
|
|
389
|
-
});
|
|
390
|
-
} else {
|
|
391
|
-
state.form[idx][key] = v;
|
|
392
|
-
}
|
|
393
|
-
});
|
|
379
|
+
// 数据路径处理
|
|
380
|
+
item._data = props.data;
|
|
381
|
+
(item.paths?.split('.') || [])?.forEach((i: any) => {
|
|
382
|
+
if (item._data[i]) {
|
|
383
|
+
item._data = item._data[i];
|
|
394
384
|
}
|
|
395
|
-
};
|
|
396
|
-
// 执行一次
|
|
397
|
-
onces?.forEach((item: any = {}) => {
|
|
398
|
-
runsetup(item);
|
|
399
385
|
});
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
)
|
|
415
|
-
|
|
386
|
+
return item;
|
|
387
|
+
});
|
|
388
|
+
const runsetup = (item: any = {}) => {
|
|
389
|
+
if (generation !== fieldWatcherGeneration) return;
|
|
390
|
+
const { idx = null, key = null, value = null, setup = null }: any = item || {};
|
|
391
|
+
const target = state.form[idx];
|
|
392
|
+
if (target && isFunction(setup)) {
|
|
393
|
+
const runId = (taskRuns.get(item) || 0) + 1;
|
|
394
|
+
taskRuns.set(item, runId);
|
|
395
|
+
const v = item.hasInitialResult ? item.initialResult : setup(deepcopy(props.data), target, route, router);
|
|
396
|
+
item.hasInitialResult = false;
|
|
397
|
+
const isCurrent = () => generation === fieldWatcherGeneration && state.form[idx] === target && taskRuns.get(item) === runId;
|
|
398
|
+
nextTick(() => {
|
|
399
|
+
if (!isCurrent()) return;
|
|
400
|
+
if (v instanceof Promise) {
|
|
401
|
+
target[key] = value;
|
|
402
|
+
v.then((res: any) => {
|
|
403
|
+
if (isCurrent()) {
|
|
404
|
+
target[key] = res;
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
} else {
|
|
408
|
+
target[key] = v;
|
|
409
|
+
}
|
|
410
|
+
});
|
|
416
411
|
}
|
|
412
|
+
};
|
|
413
|
+
// 不声明 watch 的任务只执行一次
|
|
414
|
+
onces.forEach((item: any = {}) => {
|
|
415
|
+
runsetup(item);
|
|
416
|
+
});
|
|
417
|
+
// 每个动态属性只建立一个 watcher,多个依赖在同一轮变化时只执行一次
|
|
418
|
+
watched.forEach((item: any = {}) => {
|
|
419
|
+
unwatchs.push(
|
|
420
|
+
watch(
|
|
421
|
+
() => item.watch.map((key: any) => props.data[key]),
|
|
422
|
+
() => {
|
|
423
|
+
runsetup(item);
|
|
424
|
+
},
|
|
425
|
+
{ deep: true, immediate: true },
|
|
426
|
+
),
|
|
427
|
+
);
|
|
428
|
+
});
|
|
429
|
+
};
|
|
430
|
+
watch(
|
|
431
|
+
() => props.form,
|
|
432
|
+
(form = []) => {
|
|
433
|
+
rebuildFieldWatchers(form);
|
|
417
434
|
},
|
|
418
435
|
{ deep: true, immediate: true },
|
|
419
436
|
);
|
|
437
|
+
watch(
|
|
438
|
+
[() => props.data, () => props.idx],
|
|
439
|
+
() => {
|
|
440
|
+
rebuildFieldWatchers(props.form);
|
|
441
|
+
},
|
|
442
|
+
);
|
|
420
443
|
|
|
421
444
|
// 处理
|
|
422
445
|
watch(
|
|
@@ -440,8 +463,6 @@
|
|
|
440
463
|
);
|
|
441
464
|
|
|
442
465
|
onBeforeUnmount(() => {
|
|
443
|
-
|
|
444
|
-
unwatch();
|
|
445
|
-
});
|
|
466
|
+
clearFieldWatchers();
|
|
446
467
|
});
|
|
447
468
|
</script>
|