@neatui/vue 2.17.1 → 2.17.3
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/IFollowView.vue +124 -41
- package/src/components/form/Checkbox.vue +61 -46
- package/src/components/form/CheckboxGroup.vue +74 -0
- package/src/components/form/CheckboxItem.vue +87 -0
- package/src/components/form/DateView@v3.vue +38 -19
- package/src/components/form/Input@v3.vue +34 -34
- package/src/components/form/InputNumber.vue +46 -25
- package/src/components/form/{Textarea@v2.vue → Textarea.vue} +1 -3
- package/src/components/form/index.ts +5 -3
- package/src/components/loader/FormLoader/FormLoader.vue +422 -0
- package/src/components/loader/FormLoader/FormLoader@v2.vue +2 -0
- package/src/components/form/DateRangePicker@v2.vue.backup +0 -224
- package/src/components/form/Input.vue.backup +0 -230
- package/src/components/form/MoreSelect.vue.backup +0 -144
- package/src/components/form/SearchSelect.vue.backup +0 -194
- package/src/components/form/TextArea.vue +0 -193
- package/src/components/form/date.ts +0 -321
- package/src/components/loader/FormLoader/FormLoader@v3.vue.backup +0 -399
- package/src/components/loader/FormLoader/FormRender@v3.vue.backup +0 -4
package/package.json
CHANGED
|
@@ -3,24 +3,33 @@
|
|
|
3
3
|
<slot>
|
|
4
4
|
<button ui-btn="@a s case :border"><i class="icon icon-dropdown"></i></button>
|
|
5
5
|
</slot>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
</div>
|
|
7
|
+
<Teleport v-if="$slots.tips" to="#ifollow">
|
|
8
|
+
<div
|
|
9
|
+
ref="tip"
|
|
10
|
+
:class="`${tipClass}${mobile ? ' fekit-follow-mobile' : ''}`"
|
|
11
|
+
:style="`position: fixed; pointer-events: none; ${tipStyle}`"
|
|
12
|
+
ui-tips="@a"
|
|
13
|
+
:ui-tips-view="state.show ? 1 : 0"
|
|
14
|
+
@mouseover="hovershow"
|
|
15
|
+
@mouseout="hoverhide"
|
|
16
|
+
@click="clickhide"
|
|
17
|
+
>
|
|
18
|
+
<div ref="box" :ui-tips-box="state.pos" :class="tipBoxClass" :style="tipBoxStyle">
|
|
19
|
+
<div ui-hide=">mob" class="mob-follow-tips w-full n-ss" ui-flex="row xm">
|
|
20
|
+
<div class="w-sm"></div>
|
|
21
|
+
<div>
|
|
22
|
+
<h5 class="bold">{{ title }}</h5>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="w-sm" ui-flex="row rm">
|
|
25
|
+
<button ui-btn="@a none s :square" @click="toggle"><i class="icon icon-close"></i></button>
|
|
26
|
+
</div>
|
|
20
27
|
</div>
|
|
28
|
+
<slot name="tips"></slot>
|
|
29
|
+
<div v-if="arrow" ui-tips-arrow="" v-bind="arrow"></div>
|
|
21
30
|
</div>
|
|
22
|
-
</
|
|
23
|
-
</
|
|
31
|
+
</div>
|
|
32
|
+
</Teleport>
|
|
24
33
|
</template>
|
|
25
34
|
<script setup lang="ts">
|
|
26
35
|
import { reactive, ref, onMounted, onUnmounted, watch } from 'vue';
|
|
@@ -48,6 +57,8 @@
|
|
|
48
57
|
tipBoxStyle?: string;
|
|
49
58
|
arrow?: any;
|
|
50
59
|
clickTipHide?: boolean;
|
|
60
|
+
mobile?: boolean;
|
|
61
|
+
title?: string;
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
// 入参
|
|
@@ -63,6 +74,8 @@
|
|
|
63
74
|
tipBoxStyle: '',
|
|
64
75
|
arrow: {},
|
|
65
76
|
clickTipHide: false,
|
|
77
|
+
mobile: true,
|
|
78
|
+
title: '',
|
|
66
79
|
});
|
|
67
80
|
|
|
68
81
|
const dom: any = ref(null);
|
|
@@ -74,6 +87,7 @@
|
|
|
74
87
|
pos: props.pos,
|
|
75
88
|
hover: 0,
|
|
76
89
|
tipdom: false,
|
|
90
|
+
isMobile: false,
|
|
77
91
|
});
|
|
78
92
|
|
|
79
93
|
const showTimer: any = ref(null);
|
|
@@ -148,42 +162,47 @@
|
|
|
148
162
|
}
|
|
149
163
|
};
|
|
150
164
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// state.tipdom = false;
|
|
159
|
-
// }, 10);
|
|
160
|
-
// },
|
|
161
|
-
// true
|
|
162
|
-
// );
|
|
165
|
+
// 阻止触摸事件冒泡和默认行为
|
|
166
|
+
const preventTouchScroll = (e: TouchEvent) => {
|
|
167
|
+
// 只有当触摸点在遮罩层本身时才阻止,不影响子元素
|
|
168
|
+
if (e.target === tip.value && tip.value?.classList.contains('fekit-follow-mobile')) {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
e.stopPropagation();
|
|
171
|
+
}
|
|
163
172
|
};
|
|
164
173
|
|
|
165
174
|
onMounted(() => {
|
|
166
175
|
document.addEventListener('click', cancel, true);
|
|
176
|
+
// 添加触摸事件监听器以防止页面滚动
|
|
177
|
+
document.addEventListener('touchstart', preventTouchScroll, { passive: false });
|
|
178
|
+
document.addEventListener('touchmove', preventTouchScroll, { passive: false });
|
|
179
|
+
// 判断是否为移动端
|
|
180
|
+
state.isMobile = window.innerWidth < 800;
|
|
167
181
|
});
|
|
168
182
|
|
|
169
183
|
const ex: any = ref(null);
|
|
170
184
|
watch([() => dom.value, () => tip.value], () => {
|
|
171
185
|
if (dom.value && tip.value) {
|
|
172
|
-
ex.value = new Follow(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
186
|
+
ex.value = new Follow(
|
|
187
|
+
dom.value,
|
|
188
|
+
tip.value,
|
|
189
|
+
(status) => {
|
|
190
|
+
if (!props?.pos?.includes(':fixed')) {
|
|
191
|
+
if (status === 'b') {
|
|
192
|
+
const _pos = props?.pos?.replace(/b/g, 't');
|
|
193
|
+
if (_pos) {
|
|
194
|
+
state.pos = _pos;
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
const _pos = props?.pos?.replace(/t/g, 'b');
|
|
198
|
+
if (_pos) {
|
|
199
|
+
state.pos = _pos;
|
|
200
|
+
}
|
|
183
201
|
}
|
|
184
202
|
}
|
|
185
|
-
}
|
|
186
|
-
|
|
203
|
+
},
|
|
204
|
+
{ hideOnScrollOut: false },
|
|
205
|
+
);
|
|
187
206
|
} else {
|
|
188
207
|
ex.value = null;
|
|
189
208
|
}
|
|
@@ -191,6 +210,9 @@
|
|
|
191
210
|
|
|
192
211
|
onUnmounted(() => {
|
|
193
212
|
document.removeEventListener('click', cancel, true);
|
|
213
|
+
// 移除触摸事件监听器
|
|
214
|
+
document.removeEventListener('touchstart', preventTouchScroll);
|
|
215
|
+
document.removeEventListener('touchmove', preventTouchScroll);
|
|
194
216
|
state.show = 0;
|
|
195
217
|
|
|
196
218
|
if (ex.value) {
|
|
@@ -218,3 +240,64 @@
|
|
|
218
240
|
cancel,
|
|
219
241
|
});
|
|
220
242
|
</script>
|
|
243
|
+
<style lang="scss">
|
|
244
|
+
@use '@neatui/css' as neatui;
|
|
245
|
+
@include neatui.mob {
|
|
246
|
+
.fekit-follow-mobile {
|
|
247
|
+
position: fixed !important;
|
|
248
|
+
width: 100% !important;
|
|
249
|
+
height: 100% !important;
|
|
250
|
+
|
|
251
|
+
display: flex !important;
|
|
252
|
+
flex-direction: column !important;
|
|
253
|
+
justify-content: flex-end !important;
|
|
254
|
+
align-items: center !important;
|
|
255
|
+
align-content: center !important;
|
|
256
|
+
inset: 0 0 0 0 !important;
|
|
257
|
+
|
|
258
|
+
&[ui-tips-view='1'] {
|
|
259
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
260
|
+
pointer-events: auto !important;
|
|
261
|
+
touch-action: none !important;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
&[ui-tips~='@a'] [ui-tips-box] {
|
|
265
|
+
position: relative !important;
|
|
266
|
+
|
|
267
|
+
width: 100% !important;
|
|
268
|
+
bottom: env(safe-area-inset-bottom) !important;
|
|
269
|
+
right: unset !important;
|
|
270
|
+
top: unset !important;
|
|
271
|
+
left: unset !important;
|
|
272
|
+
transform: translate3d(0, 0.5em, 0);
|
|
273
|
+
|
|
274
|
+
display: flex !important;
|
|
275
|
+
flex-direction: column !important;
|
|
276
|
+
justify-content: flex-end !important;
|
|
277
|
+
align-items: center !important;
|
|
278
|
+
align-content: center !important;
|
|
279
|
+
|
|
280
|
+
[ui-tips-arrow] {
|
|
281
|
+
display: none;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.mob-follow-tips {
|
|
287
|
+
position: relative;
|
|
288
|
+
padding-bottom: env(safe-area-inset-bottom, 16px);
|
|
289
|
+
&::before {
|
|
290
|
+
position: absolute;
|
|
291
|
+
content: '';
|
|
292
|
+
display: block;
|
|
293
|
+
width: 4rem;
|
|
294
|
+
height: 3px;
|
|
295
|
+
border-radius: 1em;
|
|
296
|
+
background-color: var(--co-text-o-ss);
|
|
297
|
+
top: 5px;
|
|
298
|
+
left: 50%;
|
|
299
|
+
transform: translateX(-50%);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
</style>
|
|
@@ -1,64 +1,79 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
<CheckboxGroup v-if="isMultiple" v-bind="groupBindings" :modelValue="arrayValue" @update:modelValue="emitValue">
|
|
3
|
+
<template #default="slotProps">
|
|
4
|
+
<slot v-bind="slotProps" />
|
|
5
|
+
</template>
|
|
6
|
+
</CheckboxGroup>
|
|
7
|
+
<Checkbox v-else v-bind="singleBindings" :modelValue="modelValue" @update:modelValue="emitValue">
|
|
8
|
+
<template #default="slotProps">
|
|
9
|
+
<slot v-bind="slotProps" />
|
|
10
|
+
</template>
|
|
11
|
+
</Checkbox>
|
|
10
12
|
</template>
|
|
13
|
+
|
|
11
14
|
<script setup lang="ts">
|
|
12
|
-
import {
|
|
15
|
+
import { computed } from 'vue';
|
|
16
|
+
import Checkbox from './CheckboxItem.vue';
|
|
17
|
+
import CheckboxGroup from './CheckboxGroup.vue';
|
|
18
|
+
|
|
19
|
+
type ValueType = any | { label?: string; value: any };
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
interface OptionsTypes {
|
|
21
|
+
interface OptionType {
|
|
16
22
|
label: string;
|
|
17
|
-
value
|
|
23
|
+
value?: any;
|
|
18
24
|
disabled?: boolean;
|
|
19
25
|
}
|
|
26
|
+
|
|
20
27
|
interface Props {
|
|
21
|
-
modelValue
|
|
22
|
-
|
|
28
|
+
modelValue?: any | any[];
|
|
29
|
+
label?: string;
|
|
30
|
+
disabled?: boolean;
|
|
23
31
|
theme?: string;
|
|
32
|
+
attrs?: any;
|
|
33
|
+
checkedValue?: ValueType;
|
|
34
|
+
defaultValue?: ValueType;
|
|
35
|
+
options?: (OptionType | string)[] | [ValueType, ValueType];
|
|
36
|
+
required?: boolean;
|
|
24
37
|
}
|
|
25
|
-
|
|
38
|
+
|
|
26
39
|
const props = withDefaults(defineProps<Props>(), {
|
|
40
|
+
modelValue: () => false,
|
|
27
41
|
theme: '@a',
|
|
28
|
-
|
|
42
|
+
disabled: false,
|
|
43
|
+
label: '',
|
|
44
|
+
attrs: () => ({}),
|
|
45
|
+
checkedValue: () => true,
|
|
46
|
+
defaultValue: () => false,
|
|
47
|
+
required: false,
|
|
29
48
|
options: () => [],
|
|
30
49
|
});
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
const emit = defineEmits<{
|
|
52
|
+
(e: 'update:modelValue', value: any | any[]): void;
|
|
53
|
+
}>();
|
|
34
54
|
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
const isMultiple = computed(() => Array.isArray(props.modelValue));
|
|
56
|
+
const arrayValue = computed(() => (Array.isArray(props.modelValue) ? props.modelValue : []));
|
|
57
|
+
|
|
58
|
+
const singleOptions = computed(() => (Array.isArray(props.options) && props.options.length === 2 ? (props.options as [ValueType, ValueType]) : undefined));
|
|
59
|
+
|
|
60
|
+
const singleBindings = computed(() => ({
|
|
61
|
+
label: props.label,
|
|
62
|
+
disabled: props.disabled,
|
|
63
|
+
theme: props.theme,
|
|
64
|
+
attrs: props.attrs,
|
|
65
|
+
checkedValue: props.checkedValue,
|
|
66
|
+
defaultValue: props.defaultValue,
|
|
67
|
+
options: singleOptions.value,
|
|
68
|
+
required: props.required,
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
const groupBindings = computed(() => ({
|
|
72
|
+
options: props.options as (OptionType | string)[],
|
|
73
|
+
disabled: props.disabled,
|
|
74
|
+
theme: props.theme,
|
|
75
|
+
attrs: props.attrs,
|
|
76
|
+
}));
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
watch(
|
|
42
|
-
[() => props.options, () => props.modelValue],
|
|
43
|
-
([options, value]) => {
|
|
44
|
-
const lists = options?.map((item) => ({ ...item, __checked: value?.includes(item.value) }));
|
|
45
|
-
// 只有在内容变化时才更新
|
|
46
|
-
if (JSON.stringify(state.lists) !== JSON.stringify(lists)) {
|
|
47
|
-
state.lists = lists;
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
immediate: true,
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
|
-
watch(
|
|
55
|
-
() => state.lists,
|
|
56
|
-
(val) => {
|
|
57
|
-
const value = val.filter((item: any) => item.__checked).map((item: any) => item.value);
|
|
58
|
-
emits('update:modelValue', value);
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
deep: true,
|
|
62
|
-
},
|
|
63
|
-
);
|
|
78
|
+
const emitValue = (value: any | any[]) => emit('update:modelValue', value);
|
|
64
79
|
</script>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<form class="m-sm-sub">
|
|
3
|
+
<label v-for="(item, idx) in normalizedOptions" :key="idx" :ui-form="`${theme} type:checkbox${item.disabled ? ' disabled' : ''}`" v-bind="attrs">
|
|
4
|
+
<input type="checkbox" :checked="isChecked(item.value)" :disabled="item.disabled" @change="handleChange(item.value, $event)" />
|
|
5
|
+
<slot :item="item" :index="idx">
|
|
6
|
+
<span>{{ item.label }}</span>
|
|
7
|
+
</slot>
|
|
8
|
+
</label>
|
|
9
|
+
</form>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup lang="ts">
|
|
13
|
+
import { computed } from 'vue';
|
|
14
|
+
|
|
15
|
+
interface OptionType {
|
|
16
|
+
label: string;
|
|
17
|
+
value?: any;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Props {
|
|
22
|
+
modelValue?: any[];
|
|
23
|
+
options?: (OptionType | string)[];
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
theme?: string;
|
|
26
|
+
attrs?: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
30
|
+
modelValue: () => [],
|
|
31
|
+
options: () => [],
|
|
32
|
+
disabled: false,
|
|
33
|
+
theme: '@a',
|
|
34
|
+
attrs: () => ({}),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const emits = defineEmits<{
|
|
38
|
+
(e: 'update:modelValue', value: any[]): void;
|
|
39
|
+
}>();
|
|
40
|
+
|
|
41
|
+
// 规范化 options
|
|
42
|
+
const normalizedOptions = computed(() => {
|
|
43
|
+
return props.options.map((item) =>
|
|
44
|
+
typeof item === 'string'
|
|
45
|
+
? { label: item, value: item, disabled: props.disabled }
|
|
46
|
+
: {
|
|
47
|
+
label: item?.label ?? '',
|
|
48
|
+
value: 'value' in item ? item.value : item?.label,
|
|
49
|
+
disabled: item?.disabled ?? props.disabled,
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// 判断某个值是否被选中
|
|
55
|
+
const isChecked = (value: any) => {
|
|
56
|
+
return props.modelValue.includes(value);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// 处理选中状态变化
|
|
60
|
+
const handleChange = (value: any, e: Event) => {
|
|
61
|
+
const checked = (e.target as HTMLInputElement).checked;
|
|
62
|
+
let newValue: any[];
|
|
63
|
+
|
|
64
|
+
if (checked) {
|
|
65
|
+
// 添加到选中列表
|
|
66
|
+
newValue = [...props.modelValue, value];
|
|
67
|
+
} else {
|
|
68
|
+
// 从选中列表移除
|
|
69
|
+
newValue = props.modelValue.filter((v) => v !== value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
emits('update:modelValue', newValue);
|
|
73
|
+
};
|
|
74
|
+
</script>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<label :ui-form="`${theme} type:checkbox${disabled ? ' disabled' : ''}`" v-bind="attrs">
|
|
3
|
+
<input type="checkbox" :checked="isChecked" :disabled="disabled" @change="handleChange" />
|
|
4
|
+
<slot :item="slotItem">
|
|
5
|
+
<span v-if="label">{{ label }}</span>
|
|
6
|
+
</slot>
|
|
7
|
+
</label>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import { computed, onMounted } from 'vue';
|
|
12
|
+
|
|
13
|
+
type ValueType = any | { label?: string; value: any };
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
modelValue?: any;
|
|
17
|
+
label?: string;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
theme?: string;
|
|
20
|
+
attrs?: any;
|
|
21
|
+
checkedValue?: ValueType;
|
|
22
|
+
defaultValue?: ValueType;
|
|
23
|
+
options?: [ValueType, ValueType]; // [checkedValue, defaultValue]
|
|
24
|
+
required?: boolean; // 是否必填,必填时自动初始化为 defaultValue
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
28
|
+
modelValue: () => false,
|
|
29
|
+
theme: '@a',
|
|
30
|
+
disabled: false,
|
|
31
|
+
label: '',
|
|
32
|
+
attrs: () => ({}),
|
|
33
|
+
checkedValue: () => true,
|
|
34
|
+
defaultValue: () => false,
|
|
35
|
+
required: false,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const emits = defineEmits<{
|
|
39
|
+
(e: 'update:modelValue', value: any): void;
|
|
40
|
+
}>();
|
|
41
|
+
|
|
42
|
+
// 获取实际的值(支持对象和基本类型)
|
|
43
|
+
const getActualValue = (val: ValueType) => {
|
|
44
|
+
return val && typeof val === 'object' && 'value' in val ? val.value : val;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// 优先使用 options,否则使用 checkedValue/defaultValue
|
|
48
|
+
const actualCheckedValue = computed(() => {
|
|
49
|
+
const checkedVal = props.options ? props.options[0] : props.checkedValue;
|
|
50
|
+
return getActualValue(checkedVal);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const actualDefaultValue = computed(() => {
|
|
54
|
+
const defaultVal = props.options ? props.options[1] : props.defaultValue;
|
|
55
|
+
return getActualValue(defaultVal);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const slotItem = computed(() => {
|
|
59
|
+
if (props.options && props.options.length) {
|
|
60
|
+
const checkedVal = props.options[0];
|
|
61
|
+
const label = checkedVal && typeof checkedVal === 'object' && 'label' in checkedVal ? checkedVal.label : props.label;
|
|
62
|
+
return { label, value: getActualValue(checkedVal) };
|
|
63
|
+
}
|
|
64
|
+
return { label: props.label, value: actualCheckedValue.value };
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// 判断是否选中
|
|
68
|
+
const isChecked = computed(() => {
|
|
69
|
+
return props.modelValue === actualCheckedValue.value;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const handleChange = (e: Event) => {
|
|
73
|
+
const checked = (e.target as HTMLInputElement).checked;
|
|
74
|
+
emits('update:modelValue', checked ? actualCheckedValue.value : actualDefaultValue.value);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// 如果是必填项,且值不是有效的 checkedValue 或 defaultValue,自动初始化为 defaultValue
|
|
78
|
+
onMounted(() => {
|
|
79
|
+
if (props.required) {
|
|
80
|
+
const currentVal = props.modelValue;
|
|
81
|
+
const isValidValue = currentVal === actualCheckedValue.value || currentVal === actualDefaultValue.value;
|
|
82
|
+
if (!isValidValue) {
|
|
83
|
+
emits('update:modelValue', actualDefaultValue.value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
</script>
|
|
@@ -30,11 +30,7 @@
|
|
|
30
30
|
<div v-if="state.type === 2" class="full">
|
|
31
31
|
<ul ui-grid="mob:4" class="n-ms ny-sm-sub">
|
|
32
32
|
<li v-for="(year, idx) in panel.years" :key="idx" ui-flex="col cm" @click="setDateValue('y', year)">
|
|
33
|
-
<div
|
|
34
|
-
ui-flex="col cm"
|
|
35
|
-
class="w-ss h-xs ac ux-none r-sm"
|
|
36
|
-
:class="isSelectedYear(year) ? 'active bg-main-o-lm co-w' : 'co-main:hover'"
|
|
37
|
-
>
|
|
33
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedYear(year) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">
|
|
38
34
|
{{ year }}
|
|
39
35
|
</div>
|
|
40
36
|
</li>
|
|
@@ -42,18 +38,42 @@
|
|
|
42
38
|
</div>
|
|
43
39
|
<div v-else-if="state.type === 1" class="full">
|
|
44
40
|
<ul ui-grid="mob:4" class="n-ms ny-sm-sub">
|
|
45
|
-
<li ui-flex="col cm" @click="setDateValue('m', 1)"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<li ui-flex="col cm" @click="setDateValue('m',
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<li ui-flex="col cm" @click="setDateValue('m',
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<li ui-flex="col cm" @click="setDateValue('m',
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
<li ui-flex="col cm" @click="setDateValue('m', 1)">
|
|
42
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(1) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">1月</div>
|
|
43
|
+
</li>
|
|
44
|
+
<li ui-flex="col cm" @click="setDateValue('m', 2)">
|
|
45
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(2) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">2月</div>
|
|
46
|
+
</li>
|
|
47
|
+
<li ui-flex="col cm" @click="setDateValue('m', 3)">
|
|
48
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(3) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">3月</div>
|
|
49
|
+
</li>
|
|
50
|
+
<li ui-flex="col cm" @click="setDateValue('m', 4)">
|
|
51
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(4) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">4月</div>
|
|
52
|
+
</li>
|
|
53
|
+
<li ui-flex="col cm" @click="setDateValue('m', 5)">
|
|
54
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(5) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">5月</div>
|
|
55
|
+
</li>
|
|
56
|
+
<li ui-flex="col cm" @click="setDateValue('m', 6)">
|
|
57
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(6) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">6月</div>
|
|
58
|
+
</li>
|
|
59
|
+
<li ui-flex="col cm" @click="setDateValue('m', 7)">
|
|
60
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(7) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">7月</div>
|
|
61
|
+
</li>
|
|
62
|
+
<li ui-flex="col cm" @click="setDateValue('m', 8)">
|
|
63
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(8) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">8月</div>
|
|
64
|
+
</li>
|
|
65
|
+
<li ui-flex="col cm" @click="setDateValue('m', 9)">
|
|
66
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(9) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">9月</div>
|
|
67
|
+
</li>
|
|
68
|
+
<li ui-flex="col cm" @click="setDateValue('m', 10)">
|
|
69
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(10) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">10月</div>
|
|
70
|
+
</li>
|
|
71
|
+
<li ui-flex="col cm" @click="setDateValue('m', 11)">
|
|
72
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(11) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">11月</div>
|
|
73
|
+
</li>
|
|
74
|
+
<li ui-flex="col cm" @click="setDateValue('m', 12)">
|
|
75
|
+
<div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(12) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">12月</div>
|
|
76
|
+
</li>
|
|
57
77
|
</ul>
|
|
58
78
|
</div>
|
|
59
79
|
<div v-else class="full">
|
|
@@ -161,8 +181,7 @@
|
|
|
161
181
|
</template>
|
|
162
182
|
<script setup lang="ts">
|
|
163
183
|
import { computed, ref, reactive, watch, onMounted } from 'vue';
|
|
164
|
-
import { isDateString, isObject, isString } from '@fekit/utils';
|
|
165
|
-
import { idate } from './date';
|
|
184
|
+
import { idate, isDateString, isObject, isString } from '@fekit/utils';
|
|
166
185
|
import { Icon } from '../basic';
|
|
167
186
|
|
|
168
187
|
const normalizeDateInput = (value: any) => {
|