@neatui/vue 2.11.0 → 2.15.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 +7 -7
- package/src/components/form/MoreSelect@v3.vue +85 -15
- 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 +227 -20
- 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 +33 -58
- 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/TableRender.vue +1 -1
- 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
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
v-if="item.day"
|
|
46
46
|
:ui-date-day="item.day"
|
|
47
47
|
class="flex-block"
|
|
48
|
-
:class="`${item.range ? 'bg-main-xs' : ''} ${item.sta ? 'r-lt-sl r-lb-sl' : ''} ${item.end ? 'r-rt-sl r-rb-sl' : ''}`"
|
|
48
|
+
:class="`${item.range ? 'bg-main-o-xs' : ''} ${item.sta ? 'r-lt-sl r-lb-sl' : ''} ${item.end ? 'r-rt-sl r-rb-sl' : ''}`"
|
|
49
49
|
ui-flex="col cm"
|
|
50
50
|
@click="change(item)"
|
|
51
51
|
@mouseenter="setRangeValue(item)"
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
ui-flex="col cm"
|
|
55
55
|
class="r-sm b-solid bk-none b-xs my-ss ux-scale"
|
|
56
56
|
style="width: 1.8em; height: 1.8em"
|
|
57
|
-
:class="`${item.isLastMonth || item.isNextMonth ? 'co-idle' : item.isHoliday ? 'co-risk' : ''} ${item.selected ? 'active bg-main-lm co-fore' : 'hover-bg-weak'}`"
|
|
57
|
+
:class="`${item.isLastMonth || item.isNextMonth ? 'co-idle' : item.isHoliday ? 'co-risk' : ''} ${item.selected ? 'active bg-main-o-lm co-fore' : 'hover-bg-weak'}`"
|
|
58
58
|
>
|
|
59
59
|
<span>{{ item.day }}</span>
|
|
60
60
|
</div>
|
|
61
61
|
</div>
|
|
62
|
-
<div class="pa full
|
|
62
|
+
<div class="pa w-full lh-xs ny-ss ob-no ol-no nowrap s-ml bold" style="transform-origin: 50% 100%" ui-flex="row ct" v-html="extras(item)"></div>
|
|
63
63
|
</div>
|
|
64
64
|
</li>
|
|
65
65
|
</ul>
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
</div>
|
|
110
110
|
</div>
|
|
111
111
|
|
|
112
|
-
<div v-if="tools" ui-date-foot="" ui-flex="row xm" class="flex-fixed nx-sl ny-sl b-solid bk-line-mm bt-xs">
|
|
112
|
+
<div v-if="tools" ui-date-foot="" ui-flex="row xm" class="flex-fixed nx-sl ny-sl b-solid bk-line-o-mm bt-xs">
|
|
113
113
|
<div ui-flex="row lm" class="nl-ss">
|
|
114
114
|
<div v-if="state.panel" ui-flex="row lm">
|
|
115
115
|
<span :anim-editing="state.type === 'date'" ui-btn="@a xs none" class="nx-ss" @click="setPanelType('date')">{{ idate(state.panel).format('YYYY-MM-DD') }}</span>
|
|
@@ -119,8 +119,8 @@
|
|
|
119
119
|
</div>
|
|
120
120
|
<div v-else-if="state.shortcuts?.length" ui-flex="row lm">
|
|
121
121
|
<div class="mr-sm-sub nx-sl-sub ny-ss-sub lh-ss nowrap fs-ss dib-sub" ui-scroll=":x y:hidden">
|
|
122
|
-
<p v-for="(item, idx) in state.shortcuts" :key="idx" class="bg-main-ss co-main r-xl" ui-btn="@a xs none :round" @click="item?.func">{{ item?.text }}</p>
|
|
123
|
-
<p class="bg-main-ss co-main r-xl" ui-btn="@a xs none :round"><Icon class="co-main" name="more" /></p>
|
|
122
|
+
<p v-for="(item, idx) in state.shortcuts" :key="idx" class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round" @click="item?.func">{{ item?.text }}</p>
|
|
123
|
+
<p class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round"><Icon class="co-main" name="more" /></p>
|
|
124
124
|
</div>
|
|
125
125
|
</div>
|
|
126
126
|
<div> </div>
|
|
@@ -149,20 +149,20 @@
|
|
|
149
149
|
text: '昨天',
|
|
150
150
|
func() {
|
|
151
151
|
change({ date: idate(new Date().setDate(new Date().getDate() - 1)).format('YYYY-MM-DD') });
|
|
152
|
-
}
|
|
152
|
+
},
|
|
153
153
|
},
|
|
154
154
|
today: {
|
|
155
155
|
text: '今天',
|
|
156
156
|
func() {
|
|
157
157
|
change({ date: idate(new Date()).format('YYYY-MM-DD') });
|
|
158
|
-
}
|
|
158
|
+
},
|
|
159
159
|
},
|
|
160
160
|
tomorrow: {
|
|
161
161
|
text: '明天',
|
|
162
162
|
func() {
|
|
163
163
|
change({ date: idate(new Date().setDate(new Date().getDate() + 1)).format('YYYY-MM-DD') });
|
|
164
|
-
}
|
|
165
|
-
}
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
const emits: any = defineEmits(['update:modelValue', 'change', 'update']);
|
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
format: 'YYYY-MM-DD',
|
|
205
205
|
// 节假日
|
|
206
206
|
holiday: () => ({}),
|
|
207
|
-
time: false
|
|
207
|
+
time: false,
|
|
208
208
|
});
|
|
209
209
|
|
|
210
210
|
// 小时
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
} else {
|
|
251
251
|
return !props.time;
|
|
252
252
|
}
|
|
253
|
-
})
|
|
253
|
+
}),
|
|
254
254
|
});
|
|
255
255
|
|
|
256
256
|
const ths: any = ref(null);
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
// 值
|
|
290
290
|
state.value = value || '';
|
|
291
291
|
},
|
|
292
|
-
{ deep: true, immediate: true }
|
|
292
|
+
{ deep: true, immediate: true },
|
|
293
293
|
);
|
|
294
294
|
|
|
295
295
|
onMounted(() => {
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
() => state.panel,
|
|
300
300
|
() => {
|
|
301
301
|
setTimeValue();
|
|
302
|
-
}
|
|
302
|
+
},
|
|
303
303
|
);
|
|
304
304
|
|
|
305
305
|
// 更新时间
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
v-if="item.day"
|
|
68
68
|
:ui-date-day="item.day"
|
|
69
69
|
class="flex-block"
|
|
70
|
-
:class="`${item.range ? 'bg-main-xs' : ''} ${item.sta ? 'r-lt-sl r-lb-sl' : ''} ${item.end ? 'r-rt-sl r-rb-sl' : ''}`"
|
|
70
|
+
:class="`${item.range ? 'bg-main-o-xs' : ''} ${item.sta ? 'r-lt-sl r-lb-sl' : ''} ${item.end ? 'r-rt-sl r-rb-sl' : ''}`"
|
|
71
71
|
ui-flex="col cm"
|
|
72
72
|
@click="change(item)"
|
|
73
73
|
>
|
|
@@ -75,12 +75,12 @@
|
|
|
75
75
|
ui-flex="col cm"
|
|
76
76
|
class="r-sm b-solid bk-none b-xs my-ss ux-scale co-main:hover"
|
|
77
77
|
style="width: 1.8em; height: 1.8em"
|
|
78
|
-
:class="`${item.isLastMonth || item.isNextMonth ? 'co-idle' : item.isHoliday ? 'co-risk' : ''} ${item.selected ? 'active bg-main-lm co-fore' : 'hover-bg-weak'}`"
|
|
78
|
+
:class="`${item.isLastMonth || item.isNextMonth ? 'co-idle' : item.isHoliday ? 'co-risk' : ''} ${item.selected ? 'active bg-main-o-lm co-fore' : 'hover-bg-weak'}`"
|
|
79
79
|
>
|
|
80
80
|
<span>{{ item.day }}</span>
|
|
81
81
|
</div>
|
|
82
82
|
</div>
|
|
83
|
-
<div class="pa full
|
|
83
|
+
<div class="pa w-full lh-xs ny-ss ob-no ol-no nowrap s-ml bold" style="transform-origin: 50% 100%" ui-flex="row ct" v-html="extras(item)"></div>
|
|
84
84
|
</div>
|
|
85
85
|
</li>
|
|
86
86
|
</ul>
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
</ul>
|
|
130
130
|
</div>
|
|
131
131
|
</div>
|
|
132
|
-
<div v-if="tools" ui-date-foot="" ui-flex="row xm" class="flex-fixed nx-sl ny-sl b-solid bk-line-mm bt-xs">
|
|
132
|
+
<div v-if="tools" ui-date-foot="" ui-flex="row xm" class="flex-fixed nx-sl ny-sl b-solid bk-line-o-mm bt-xs">
|
|
133
133
|
<div ui-flex="row lm" class="nl-ss">
|
|
134
134
|
<div v-if="state.panel" ui-flex="row lm">
|
|
135
135
|
<span :anim-editing="state.type === 'date'" class="nx-ss">{{ idate(state.panel).format('YYYY-MM-DD') }}</span>
|
|
@@ -137,8 +137,8 @@
|
|
|
137
137
|
</div>
|
|
138
138
|
<div v-else-if="state.shortcuts?.length" ui-flex="row lm">
|
|
139
139
|
<div class="mr-sm-sub nx-sl-sub ny-ss-sub lh-ss nowrap fs-ss dib-sub" ui-scroll=":x y:hidden">
|
|
140
|
-
<p v-for="(item, idx) in state.shortcuts" :key="idx" class="bg-main-ss co-main r-xl" ui-btn="@a xs none :round" @click="item?.func">{{ item?.text }}</p>
|
|
141
|
-
<p class="bg-main-ss co-main r-xl" ui-btn="@a xs none :round"><Icon class="co-main" name="more" /></p>
|
|
140
|
+
<p v-for="(item, idx) in state.shortcuts" :key="idx" class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round" @click="item?.func">{{ item?.text }}</p>
|
|
141
|
+
<p class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round"><Icon class="co-main" name="more" /></p>
|
|
142
142
|
</div>
|
|
143
143
|
</div>
|
|
144
144
|
<div> </div>
|
|
@@ -153,10 +153,11 @@
|
|
|
153
153
|
<script setup lang="ts">
|
|
154
154
|
import { computed, ref, reactive, watch, onMounted } from 'vue';
|
|
155
155
|
import { isDateString, isObject, isString } from '@fekit/utils';
|
|
156
|
-
import { idate } from '@fekit/utils';
|
|
156
|
+
// import { idate } from '@fekit/utils';
|
|
157
|
+
import { idate } from './date';
|
|
157
158
|
import { Icon } from '../basic';
|
|
158
159
|
|
|
159
|
-
const _level: any = { 0: ['d', 1], 1: ['m', 1], 2: ['y', 10], 3: ['y', 100] };
|
|
160
|
+
// const _level: any = { 0: ['d', 1], 1: ['m', 1], 2: ['y', 10], 3: ['y', 100] };
|
|
160
161
|
|
|
161
162
|
// 创建日期
|
|
162
163
|
const cDate = (date: any = null) => {
|
|
@@ -250,11 +251,12 @@
|
|
|
250
251
|
// 内部数据
|
|
251
252
|
const state: any = reactive({
|
|
252
253
|
// 面板显示时间
|
|
253
|
-
panel:
|
|
254
|
+
panel: undefined,
|
|
254
255
|
// 面板年份选择
|
|
255
256
|
years: 0,
|
|
256
257
|
// 当前时间计算
|
|
257
258
|
curr: computed(() => {
|
|
259
|
+
// console.log(158, state.panel);
|
|
258
260
|
const date = idate(state.panel);
|
|
259
261
|
const days = date.calendar({ group: true, value: [state.panel] });
|
|
260
262
|
return { days, ...date.attr };
|
|
@@ -262,7 +264,7 @@
|
|
|
262
264
|
// 当前面板类型
|
|
263
265
|
type: 0,
|
|
264
266
|
// 值
|
|
265
|
-
value:
|
|
267
|
+
value: undefined,
|
|
266
268
|
// 快捷选择
|
|
267
269
|
shortcuts: computed(() => {
|
|
268
270
|
return props.shortcuts.map((item: any) => {
|
|
@@ -337,9 +339,9 @@
|
|
|
337
339
|
() => props.modelValue,
|
|
338
340
|
(value: any) => {
|
|
339
341
|
// 面板显示日期
|
|
340
|
-
state.panel = value ||
|
|
342
|
+
state.panel = value || undefined;
|
|
341
343
|
// 值
|
|
342
|
-
state.value = value ||
|
|
344
|
+
state.value = value || undefined;
|
|
343
345
|
},
|
|
344
346
|
{ deep: true, immediate: true },
|
|
345
347
|
);
|
|
@@ -427,14 +429,14 @@
|
|
|
427
429
|
|
|
428
430
|
// 清空日期
|
|
429
431
|
const remove = () => {
|
|
430
|
-
state.panel =
|
|
432
|
+
state.panel = undefined;
|
|
431
433
|
update();
|
|
432
434
|
};
|
|
433
435
|
|
|
434
436
|
// 更新数据
|
|
435
437
|
const update = () => {
|
|
436
|
-
emits('update:modelValue', state.panel ? idate(state.panel).format(props.format) :
|
|
437
|
-
emits('update', state.panel ? idate(state.panel).format(props.format) :
|
|
438
|
+
emits('update:modelValue', state.panel ? idate(state.panel).format(props.format) : undefined);
|
|
439
|
+
emits('update', state.panel ? idate(state.panel).format(props.format) : undefined);
|
|
438
440
|
};
|
|
439
441
|
|
|
440
442
|
// 面板类型
|
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
|
|
213
213
|
// 清空
|
|
214
214
|
function clear() {
|
|
215
|
-
emits('update:modelValue',
|
|
215
|
+
emits('update:modelValue', null);
|
|
216
216
|
emits('clear');
|
|
217
217
|
}
|
|
218
218
|
// 输入
|
|
@@ -230,14 +230,14 @@
|
|
|
230
230
|
e.target.value = props.modelValue;
|
|
231
231
|
return false;
|
|
232
232
|
}
|
|
233
|
-
// 数字类型
|
|
234
|
-
if (props.type === 'number' && !value && props.modelValue?.length !== 1) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
233
|
+
// 数字类型 - 移除有问题的逻辑,允许用户正常删除数字
|
|
234
|
+
// if (props.type === 'number' && !value && props.modelValue?.length !== 1) {
|
|
235
|
+
// e.target.value = props.modelValue;
|
|
236
|
+
// return false;
|
|
237
|
+
// }
|
|
238
238
|
// 输入事件
|
|
239
239
|
emits('input', e, state);
|
|
240
|
-
emits('update:modelValue', value);
|
|
240
|
+
emits('update:modelValue', value || null);
|
|
241
241
|
};
|
|
242
242
|
// 失焦
|
|
243
243
|
const blur = (e: any) => {
|
|
@@ -13,17 +13,24 @@
|
|
|
13
13
|
</Input>
|
|
14
14
|
</slot>
|
|
15
15
|
<template #tips>
|
|
16
|
-
<
|
|
17
|
-
<
|
|
16
|
+
<div v-if="search" class="ny-sm nx-sl">
|
|
17
|
+
<Input v-model="state.search" sz="s">
|
|
18
|
+
<template #suffix>
|
|
19
|
+
<i ui-form-search="" class="co-note"></i>
|
|
20
|
+
</template>
|
|
21
|
+
</Input>
|
|
22
|
+
</div>
|
|
23
|
+
<ul v-if="state.filter?.length" ui-scroll=":y s" class="nx-sm lh-ml" style="min-width: 100%; max-height: 15em">
|
|
24
|
+
<template v-for="(item, idx) of state.filter" :key="idx">
|
|
18
25
|
<li v-if="item.disabled" class="ux-hover nx-sm r-ss o-ms nowrap">
|
|
19
26
|
<label style="pointer-events: none" ui-form="@a type:checkbox :block">
|
|
20
|
-
<input type="checkbox" :name="state.name" :checked="
|
|
27
|
+
<input type="checkbox" :name="state.name" :checked="state.processedValue?.some((i: any) => `${i}` === `${item.value}`)" />
|
|
21
28
|
<del class="ml-sm">{{ item.label || item }}</del>
|
|
22
29
|
</label>
|
|
23
30
|
</li>
|
|
24
31
|
<li v-else class="ux-hover nx-sm r-ss nowrap" @click.stop="select(item.value)">
|
|
25
32
|
<label style="pointer-events: none" ui-form="@a type:checkbox :block">
|
|
26
|
-
<input type="checkbox" :name="state.name" :checked="
|
|
33
|
+
<input type="checkbox" :name="state.name" :checked="state.processedValue?.some((i: any) => `${i}` === `${item.value}`)" />
|
|
27
34
|
<span class="ml-sm">{{ item.label || item }}</span>
|
|
28
35
|
</label>
|
|
29
36
|
</li>
|
|
@@ -36,7 +43,7 @@
|
|
|
36
43
|
<div class="ux-hover nx-sm ny-ss r-ss nowrap co-main" @click.stop="allselect()">
|
|
37
44
|
<label style="pointer-events: none" ui-form="@a type:checkbox :block">
|
|
38
45
|
<input type="checkbox" :name="state.name" :checked="state.all" />
|
|
39
|
-
<span class="ml-sm">全选({{
|
|
46
|
+
<span class="ml-sm">全选({{ state.selectedCount }}/{{ state.availableCount }})</span>
|
|
40
47
|
</label>
|
|
41
48
|
</div>
|
|
42
49
|
<div>
|
|
@@ -50,8 +57,8 @@
|
|
|
50
57
|
</template>
|
|
51
58
|
|
|
52
59
|
<script setup lang="ts">
|
|
53
|
-
import { reactive, ref, computed, watch } from 'vue';
|
|
54
|
-
import { Input } from '
|
|
60
|
+
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
|
61
|
+
import { Input } from '.';
|
|
55
62
|
import { IFollowView } from '../basic';
|
|
56
63
|
const ifollow: any = ref(null);
|
|
57
64
|
|
|
@@ -64,7 +71,7 @@
|
|
|
64
71
|
* options 枚举列表
|
|
65
72
|
* tools 是否显示工具栏
|
|
66
73
|
* spare 空闲兜底内容
|
|
67
|
-
* search
|
|
74
|
+
* search 是否启用搜索框
|
|
68
75
|
*
|
|
69
76
|
* -----------------------------------------
|
|
70
77
|
* theme 主题
|
|
@@ -89,10 +96,11 @@
|
|
|
89
96
|
|
|
90
97
|
// 类型
|
|
91
98
|
interface Props {
|
|
92
|
-
modelValue?: Array<string | number
|
|
99
|
+
modelValue?: Array<string | number> | string;
|
|
93
100
|
options: Array<object>;
|
|
94
101
|
tools?: boolean;
|
|
95
102
|
spare?: string;
|
|
103
|
+
search?: boolean;
|
|
96
104
|
|
|
97
105
|
// Input
|
|
98
106
|
placeholder?: string;
|
|
@@ -120,6 +128,7 @@
|
|
|
120
128
|
options: () => [],
|
|
121
129
|
tools: true,
|
|
122
130
|
spare: '当前没有可选项',
|
|
131
|
+
search: false,
|
|
123
132
|
|
|
124
133
|
// Input
|
|
125
134
|
placeholder: '',
|
|
@@ -148,31 +157,90 @@
|
|
|
148
157
|
}),
|
|
149
158
|
show: 0,
|
|
150
159
|
value: '',
|
|
160
|
+
search: '',
|
|
161
|
+
originalType: 'array',
|
|
162
|
+
processedValue: computed(() => processInput(props.modelValue)),
|
|
151
163
|
all: computed(() => {
|
|
152
|
-
|
|
164
|
+
const availableItems = state.filter?.filter((item: any) => !item.disabled);
|
|
165
|
+
return availableItems?.length > 0 && availableItems?.every((item: any) => state.processedValue?.some((i: any) => `${i}` === `${item.value}`));
|
|
153
166
|
}),
|
|
154
167
|
has: computed(() => {
|
|
155
|
-
return
|
|
168
|
+
return state.filter?.some((item: any) => state.processedValue?.some((i: any) => `${i}` === `${item.value}`));
|
|
169
|
+
}),
|
|
170
|
+
availableCount: computed(() => {
|
|
171
|
+
return state.filter?.filter((item: any) => !item.disabled)?.length || 0;
|
|
172
|
+
}),
|
|
173
|
+
selectedCount: computed(() => {
|
|
174
|
+
const availableItems = state.filter?.filter((item: any) => !item.disabled);
|
|
175
|
+
return availableItems?.filter((item: any) => state.processedValue?.some((i: any) => `${i}` === `${item.value}`))?.length || 0;
|
|
176
|
+
}),
|
|
177
|
+
filter: computed(() => {
|
|
178
|
+
if (state.search) {
|
|
179
|
+
return props.options?.filter((item: any) => {
|
|
180
|
+
return item.label?.includes(state.search);
|
|
181
|
+
});
|
|
182
|
+
} else {
|
|
183
|
+
return props.options;
|
|
184
|
+
}
|
|
156
185
|
}),
|
|
157
186
|
});
|
|
158
187
|
|
|
188
|
+
// 处理输入数据类型转换和过滤
|
|
189
|
+
const processInput = (value: any) => {
|
|
190
|
+
let processedArray: any[] = [];
|
|
191
|
+
|
|
192
|
+
if (typeof value === 'string') {
|
|
193
|
+
state.originalType = 'string';
|
|
194
|
+
processedArray = value.trim() ? (value.includes(',') ? value.split(',').map((s: string) => s.trim()) : [value]) : [];
|
|
195
|
+
} else {
|
|
196
|
+
state.originalType = 'array';
|
|
197
|
+
processedArray = value || [];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 过滤掉在options中不存在的值
|
|
201
|
+
const validValues = processedArray.filter((val: any) =>
|
|
202
|
+
props.options?.some((option: any) => `${option.value}` === `${val}`)
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
return validValues;
|
|
206
|
+
};
|
|
207
|
+
|
|
159
208
|
// 监听外部数据
|
|
160
209
|
watch(
|
|
161
210
|
[() => props.modelValue, () => props.options],
|
|
162
211
|
([v = [], o = []]: any = []) => {
|
|
163
|
-
const
|
|
212
|
+
const processedValue = processInput(v);
|
|
213
|
+
|
|
214
|
+
// 如果过滤后的值与原始值不同,需要更新modelValue
|
|
215
|
+
const originalProcessedValue = v ? (typeof v === 'string' ?
|
|
216
|
+
(v.trim() ? (v.includes(',') ? v.split(',').map((s: string) => s.trim()) : [v]) : []) :
|
|
217
|
+
(v || [])) : [];
|
|
218
|
+
|
|
219
|
+
if (originalProcessedValue.length !== processedValue.length) {
|
|
220
|
+
// 异步更新以避免递归
|
|
221
|
+
nextTick(() => {
|
|
222
|
+
emits('update:modelValue', convertOutput(processedValue));
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const selectd: any = o?.filter((item: any) => processedValue?.some((i: any) => `${i}` === `${item.value}`))?.map((item: any) => item.label) || [];
|
|
164
227
|
state.value = selectd?.join(' Ι ') || '';
|
|
165
228
|
},
|
|
166
229
|
{ deep: true, immediate: true },
|
|
167
230
|
);
|
|
168
231
|
|
|
232
|
+
// 输出时类型转换
|
|
233
|
+
const convertOutput = (arrayValue: any[]) => {
|
|
234
|
+
return state.originalType === 'string' ? arrayValue.join(',') : arrayValue;
|
|
235
|
+
};
|
|
236
|
+
|
|
169
237
|
// 更新
|
|
170
238
|
const change = (item: any) => {
|
|
171
|
-
emits('update:modelValue', item);
|
|
239
|
+
emits('update:modelValue', convertOutput(item));
|
|
172
240
|
};
|
|
173
241
|
// 选中
|
|
174
242
|
const select = (item: any) => {
|
|
175
|
-
const s = [...
|
|
243
|
+
const s = [...state.processedValue];
|
|
176
244
|
// s?.indexOf(item) !== -1 ? s?.splice(s?.indexOf(item), 1) : s?.push(item);
|
|
177
245
|
if (s?.indexOf(item) !== -1) {
|
|
178
246
|
s?.splice(s?.indexOf(item), 1);
|
|
@@ -183,7 +251,9 @@
|
|
|
183
251
|
};
|
|
184
252
|
// 全选
|
|
185
253
|
const allselect = () => {
|
|
186
|
-
|
|
254
|
+
// 只选择可用的选项,排除禁用项
|
|
255
|
+
const availableItems = state.filter?.filter((item: any) => !item.disabled);
|
|
256
|
+
const s = state.all ? [] : availableItems?.map((item: any) => item.value);
|
|
187
257
|
change(s);
|
|
188
258
|
};
|
|
189
259
|
// 清除
|
|
@@ -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-ss bk-main-ml' : 'bk-case'}`"
|
|
7
|
+
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss bk-main-o-ml' : 'bk-case'}`"
|
|
8
8
|
class="n-sm r-ss b-solid b-xs"
|
|
9
9
|
@click.stop="select(item.value)"
|
|
10
10
|
>
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
<script setup lang="ts">
|
|
53
53
|
import { reactive, ref, computed, watch } from 'vue';
|
|
54
|
-
import { Input } from '
|
|
54
|
+
import { Input } from '.';
|
|
55
55
|
import { IFollowView, IPickerView } from '../basic';
|
|
56
56
|
const ipicker: any = ref(null);
|
|
57
57
|
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
verify: false,
|
|
140
140
|
prefix: () => [],
|
|
141
141
|
suffix: () => [],
|
|
142
|
-
interacted: false
|
|
142
|
+
interacted: false,
|
|
143
143
|
});
|
|
144
144
|
// 内部数据
|
|
145
145
|
const state: any = reactive({
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
}),
|
|
154
154
|
has: computed(() => {
|
|
155
155
|
return props.options?.some((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
|
|
156
|
-
})
|
|
156
|
+
}),
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
// 监听外部数据
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
const selectd: any = o?.filter((item: any) => v?.some((i: any) => `${i}` === `${item.value}`))?.map((item: any) => item.label) || [];
|
|
164
164
|
state.value = selectd.join(' Ι ') || '';
|
|
165
165
|
},
|
|
166
|
-
{ deep: true, immediate: true }
|
|
166
|
+
{ deep: true, immediate: true },
|
|
167
167
|
);
|
|
168
168
|
|
|
169
169
|
// 更新
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
<script setup lang="ts">
|
|
32
32
|
import { reactive, ref, computed, watch } from 'vue';
|
|
33
|
-
import { Input } from '
|
|
33
|
+
import { Input } from '.';
|
|
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-ss bk-main-ml' : 'bk-case'}`"
|
|
8
|
+
:class="`${mv?.some((i: any) => `${i}` === `${item.value}`) ? 'bg-main-o-ss bk-main-o-ml' : 'bk-case'}`"
|
|
9
9
|
class="nx-ms ny-ss r-sm b-solid b-xs pr"
|
|
10
10
|
@click.stop="select(item.value)"
|
|
11
11
|
>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
<script setup lang="ts">
|
|
56
56
|
import { reactive, ref, computed, watch } from 'vue';
|
|
57
|
-
import { Input } from '
|
|
57
|
+
import { Input } from '.';
|
|
58
58
|
import { IFollowView } from '../basic';
|
|
59
59
|
const ifollow: any = ref(null);
|
|
60
60
|
|
|
@@ -66,51 +66,51 @@
|
|
|
66
66
|
// 提示文案
|
|
67
67
|
tips: {
|
|
68
68
|
type: String,
|
|
69
|
-
default: ''
|
|
69
|
+
default: '',
|
|
70
70
|
},
|
|
71
71
|
placeholder: {
|
|
72
72
|
type: String,
|
|
73
|
-
default: ''
|
|
73
|
+
default: '',
|
|
74
74
|
},
|
|
75
75
|
modelValue: {
|
|
76
76
|
type: Array as () => any[],
|
|
77
|
-
default: () => []
|
|
77
|
+
default: () => [],
|
|
78
78
|
},
|
|
79
79
|
options: {
|
|
80
80
|
type: Array as () => any[],
|
|
81
|
-
default: () => []
|
|
81
|
+
default: () => [],
|
|
82
82
|
},
|
|
83
83
|
ui: {
|
|
84
84
|
type: Object,
|
|
85
|
-
default: () => ({ sz: 'm' })
|
|
85
|
+
default: () => ({ sz: 'm' }),
|
|
86
86
|
},
|
|
87
87
|
// 校验规则
|
|
88
88
|
rules: {
|
|
89
89
|
type: Array,
|
|
90
|
-
default: () => []
|
|
90
|
+
default: () => [],
|
|
91
91
|
},
|
|
92
92
|
// 是否是示校验图标
|
|
93
93
|
verify: {
|
|
94
94
|
type: Boolean,
|
|
95
|
-
default: false
|
|
95
|
+
default: false,
|
|
96
96
|
},
|
|
97
97
|
tools: {
|
|
98
98
|
type: Boolean,
|
|
99
|
-
default: true
|
|
99
|
+
default: true,
|
|
100
100
|
},
|
|
101
101
|
spare: {
|
|
102
102
|
type: String,
|
|
103
|
-
default: '当前没有可选项'
|
|
103
|
+
default: '当前没有可选项',
|
|
104
104
|
},
|
|
105
105
|
// 分页
|
|
106
106
|
pageInfo: {
|
|
107
107
|
type: Object,
|
|
108
|
-
default: () => ({ total: 0, pages: 0, page: 0 })
|
|
108
|
+
default: () => ({ total: 0, pages: 0, page: 0 }),
|
|
109
109
|
},
|
|
110
110
|
filterable: {
|
|
111
111
|
type: Boolean,
|
|
112
|
-
default: false
|
|
113
|
-
}
|
|
112
|
+
default: false,
|
|
113
|
+
},
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
const formName = new Date().getTime().toString();
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
}),
|
|
137
137
|
has: computed(() => {
|
|
138
138
|
return props.options?.some((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
|
|
139
|
-
})
|
|
139
|
+
}),
|
|
140
140
|
});
|
|
141
141
|
|
|
142
142
|
// 选中
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
() => {
|
|
176
176
|
change([]);
|
|
177
177
|
emit('searchChange', state.search);
|
|
178
|
-
}
|
|
178
|
+
},
|
|
179
179
|
);
|
|
180
180
|
</script>
|
|
181
181
|
<style lang="scss" scoped>
|