@neatui/nuxt 0.1.0 → 1.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/BUILD.md +128 -0
- package/README.md +98 -1
- package/SSR_COMPATIBILITY.md +201 -0
- package/USAGE.md +260 -0
- package/nuxt.config.example.ts +37 -0
- package/package.json +29 -11
- package/src/components/basic/IDraggable.vue +87 -65
- package/src/components/basic/IFollowView.vue +32 -23
- package/src/components/basic/IRouterView.vue +38 -23
- package/src/components/basic/IScrollView.vue +11 -7
- package/src/components/basic/Icon.vue +17 -17
- package/src/components/basic/LayerView/Layer.vue +33 -106
- package/src/components/basic/follow.ts +133 -0
- package/src/components/display/Calendar.vue +14 -14
- package/src/components/display/CalendarReg.vue +14 -14
- package/src/components/display/Image.vue +8 -8
- package/src/components/display/PhotoEditor.vue +36 -36
- package/src/components/display/PhotoViewer.vue +8 -8
- package/src/components/display/Tree.vue +6 -6
- package/src/components/display/TreeView.vue +4 -4
- package/src/components/display/index.ts +2 -2
- package/src/components/form/Cascader.vue +19 -19
- package/src/components/form/Checkbox.vue +64 -0
- package/src/components/form/DatePicker.vue +6 -7
- package/src/components/form/DateRangePicker@v3.vue +4 -4
- package/src/components/form/DateRangeView@v3.vue +18 -19
- package/src/components/form/DateView.vue +14 -14
- package/src/components/form/DateView@v2.vue +14 -14
- package/src/components/form/DateView@v3.vue +331 -318
- package/src/components/form/ImgUpload.vue +7 -7
- package/src/components/form/Input@v3.vue +11 -11
- package/src/components/form/MoreSelect@v3.vue +87 -17
- package/src/components/form/MoreSelectList.vue +8 -8
- package/src/components/form/MoreSelectPanel@v3.vue +3 -3
- package/src/components/form/MoreSelectPicker.vue +7 -7
- package/src/components/form/MoreSelectTags.vue +8 -8
- package/src/components/form/PageMoreSelect.vue +14 -14
- package/src/components/form/PageSelect.vue +16 -16
- package/src/components/form/SearchMoreSelect.vue +12 -12
- package/src/components/form/SearchSelect@v3.vue +3 -3
- package/src/components/form/Select@v3.vue +229 -23
- package/src/components/form/SelectList.vue +8 -8
- package/src/components/form/SelectPicker.vue +6 -6
- package/src/components/form/SelectTags.vue +7 -7
- package/src/components/form/SelectTree/SelectTree@v1.vue +5 -5
- package/src/components/form/Switch.vue +38 -103
- package/src/components/form/TextArea.vue +18 -18
- package/src/components/form/Textarea@v2.vue +275 -0
- package/src/components/form/TimeView.vue +14 -14
- package/src/components/form/Upload.vue +806 -297
- package/src/components/form/date.ts +321 -0
- package/src/components/form/index.ts +7 -5
- package/src/components/form/number.ts +3 -0
- package/src/components/form/type.ts +224 -0
- package/src/components/icon/OrderIcon.vue +113 -0
- package/src/components/loader/FormLoader/FormLoader@v2.vue +193 -195
- 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 +318 -0
- package/src/components/loader/LayerLoader/index.ts +2 -0
- package/src/components/loader/LayerLoader/style.scss +77 -0
- package/src/components/loader/LimitLoader/LimitLoader@v3.vue +39 -28
- package/src/components/loader/MoveLoader/MoveLoader.vue +628 -0
- package/src/components/loader/MoveLoader/index.ts +2 -0
- package/src/components/loader/MoveLoader/style.scss +77 -0
- package/src/components/loader/TableLoader/TableLoader.vue +227 -195
- package/src/components/loader/TableLoader/TableRender.vue +141 -0
- package/src/components/loader/TableLoader/index.ts +47 -0
- package/src/components/loader/index.ts +3 -2
- package/src/components/tools/Pagination@a.vue +17 -18
- package/src/components/tools/Pagination@b.vue +16 -16
- package/src/index.ts +2 -1
- package/src/module.ts +169 -0
- package/src/runtime/types.d.ts +36 -0
- package/src/store/{myui.ts → frame.ts} +4 -4
- package/src/utils/theme.ts +14 -0
- package/tsconfig.json +1 -1
- package/src/components/loader/FormLoader/index.ts +0 -2
- package/src/components/loader/LimitLoader/LimitLoader.vue.backup +0 -131
- package/src/components/loader/LimitLoader/LimitLoader@v2.vue.backup +0 -174
- package/src/components/loader/TableLoader/TableColView.vue +0 -115
@@ -1,12 +1,14 @@
|
|
1
1
|
<template>
|
2
|
-
<label ui-form="@a type:switch"
|
3
|
-
<input type="checkbox"
|
4
|
-
<slot
|
2
|
+
<label ui-form="@a type:switch">
|
3
|
+
<input type="checkbox" v-model="internalValue" :disabled="disabled" />
|
4
|
+
<slot>
|
5
|
+
<span>{{ text }}</span>
|
6
|
+
</slot>
|
5
7
|
</label>
|
6
8
|
</template>
|
7
9
|
|
8
10
|
<script setup lang="ts">
|
9
|
-
import { ref, watch,
|
11
|
+
import { ref, watch, PropType } from 'vue';
|
10
12
|
|
11
13
|
const props = defineProps({
|
12
14
|
theme: { type: String, default: '@a' },
|
@@ -15,121 +17,54 @@
|
|
15
17
|
block: { type: Boolean, default: true },
|
16
18
|
// 值
|
17
19
|
modelValue: {
|
18
|
-
type: [Number, Boolean],
|
19
|
-
default: false
|
20
|
+
type: [Number, Boolean, String],
|
21
|
+
default: false,
|
20
22
|
},
|
21
|
-
|
22
|
-
type: {
|
23
|
+
text: {
|
23
24
|
type: String,
|
24
|
-
default: '
|
25
|
-
},
|
26
|
-
// 提示文案
|
27
|
-
tips: {
|
28
|
-
type: String,
|
29
|
-
default: ''
|
30
|
-
},
|
31
|
-
// 内容占位
|
32
|
-
placeholder: {
|
33
|
-
type: String,
|
34
|
-
default: ''
|
35
|
-
},
|
36
|
-
// 最大长度
|
37
|
-
maxlength: {
|
38
|
-
type: Number,
|
39
|
-
default: null
|
40
|
-
},
|
41
|
-
// 最小长度
|
42
|
-
minlength: {
|
43
|
-
type: Number,
|
44
|
-
default: null
|
25
|
+
default: '',
|
45
26
|
},
|
46
27
|
// 是否禁用
|
47
28
|
disabled: {
|
48
29
|
type: Boolean,
|
49
|
-
default: false
|
50
|
-
},
|
51
|
-
// 是否中读
|
52
|
-
readonly: {
|
53
|
-
type: Boolean,
|
54
|
-
default: false
|
55
|
-
},
|
56
|
-
// 是否显示清除按钮
|
57
|
-
clearable: {
|
58
|
-
type: Boolean,
|
59
|
-
default: true
|
30
|
+
default: false,
|
60
31
|
},
|
61
|
-
|
62
|
-
rules: {
|
63
|
-
type: Array,
|
64
|
-
default: () => []
|
65
|
-
},
|
66
|
-
// 是否是示校验图标
|
67
|
-
verify: {
|
68
|
-
type: Boolean,
|
69
|
-
default: false
|
70
|
-
},
|
71
|
-
prefix: {
|
32
|
+
map: {
|
72
33
|
type: Array as PropType<any[]>,
|
73
|
-
default: () => []
|
34
|
+
default: () => [false, true],
|
74
35
|
},
|
75
|
-
suffix: {
|
76
|
-
type: Array as PropType<any[]>,
|
77
|
-
default: () => []
|
78
|
-
}
|
79
36
|
});
|
80
37
|
|
81
|
-
const
|
82
|
-
const state: any = computed(() => {
|
83
|
-
if (ready.value) {
|
84
|
-
// 提示文案
|
85
|
-
let tips = '';
|
86
|
-
// 错误类型
|
87
|
-
let type = '';
|
88
|
-
// 验证结果
|
89
|
-
let verify = '';
|
90
|
-
if (props.modelValue) {
|
91
|
-
// 有值
|
92
|
-
const res: any = props.rules?.some((rule: any) => {
|
93
|
-
const yes = rule.validator && !rule.validator(props.modelValue);
|
94
|
-
tips = rule.msg;
|
95
|
-
type = rule.type;
|
96
|
-
return yes;
|
97
|
-
});
|
98
|
-
verify = res ? 'no' : 'ok';
|
99
|
-
} else {
|
100
|
-
// 无值
|
101
|
-
const res: any = props.rules?.some((rule: any) => {
|
102
|
-
tips = rule.msg;
|
103
|
-
type = rule.type;
|
104
|
-
return rule.required;
|
105
|
-
});
|
106
|
-
verify = res ? 'no' : '';
|
107
|
-
}
|
108
|
-
if (verify !== 'no' && props.tips) {
|
109
|
-
tips = props.tips;
|
110
|
-
}
|
111
|
-
// 是否显示提示
|
112
|
-
const ontips = verify === 'no' && tips ? 'show' : '';
|
113
|
-
// 状态颜色
|
114
|
-
const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
|
115
|
-
return { tips, ontips, verify, co };
|
116
|
-
} else {
|
117
|
-
return {};
|
118
|
-
}
|
119
|
-
});
|
38
|
+
const emit = defineEmits(['update:modelValue']);
|
120
39
|
|
121
|
-
|
122
|
-
|
40
|
+
// 内部值(始终是布尔值)
|
41
|
+
const internalValue = ref(false);
|
42
|
+
|
43
|
+
// 计算内部值
|
44
|
+
const getInternalValue = (externalValue: any) => {
|
45
|
+
const index = props.map.indexOf(externalValue);
|
46
|
+
return index === 0 ? true : index === 1 ? false : Boolean(externalValue);
|
47
|
+
};
|
48
|
+
|
49
|
+
// 计算外部值
|
50
|
+
const getExternalValue = (internalValue: boolean) => {
|
51
|
+
return internalValue ? props.map[0] : props.map[1];
|
52
|
+
};
|
53
|
+
|
54
|
+
// 初始化内部值
|
55
|
+
internalValue.value = getInternalValue(props.modelValue);
|
56
|
+
|
57
|
+
// 监听外部值变化
|
123
58
|
watch(
|
124
59
|
() => props.modelValue,
|
125
60
|
(newValue) => {
|
126
|
-
|
127
|
-
}
|
61
|
+
internalValue.value = getInternalValue(newValue);
|
62
|
+
},
|
128
63
|
);
|
129
64
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
65
|
+
// 监听内部值变化,向父组件发送映射后的值
|
66
|
+
watch(internalValue, (newValue) => {
|
67
|
+
const externalValue = getExternalValue(newValue);
|
68
|
+
emit('update:modelValue', externalValue);
|
134
69
|
});
|
135
70
|
</script>
|
@@ -36,75 +36,75 @@
|
|
36
36
|
// 值
|
37
37
|
modelValue: {
|
38
38
|
type: [String, Number],
|
39
|
-
default: ''
|
39
|
+
default: '',
|
40
40
|
},
|
41
41
|
// 类型
|
42
42
|
type: {
|
43
43
|
type: String,
|
44
|
-
default: 'text'
|
44
|
+
default: 'text',
|
45
45
|
},
|
46
46
|
// 提示文案
|
47
47
|
tips: {
|
48
48
|
type: String,
|
49
|
-
default: ''
|
49
|
+
default: '',
|
50
50
|
},
|
51
51
|
// 内容占位
|
52
52
|
placeholder: {
|
53
53
|
type: String,
|
54
|
-
default: ''
|
54
|
+
default: '',
|
55
55
|
},
|
56
56
|
// 最大长度
|
57
57
|
maxLength: {
|
58
58
|
type: Number,
|
59
|
-
default: null
|
59
|
+
default: null,
|
60
60
|
},
|
61
61
|
// 最小长度
|
62
62
|
minLength: {
|
63
63
|
type: Number,
|
64
|
-
default: null
|
64
|
+
default: null,
|
65
65
|
},
|
66
66
|
// 最小长度
|
67
67
|
autoHeight: {
|
68
68
|
type: Boolean,
|
69
|
-
default: false
|
69
|
+
default: false,
|
70
70
|
},
|
71
71
|
// 是否禁用
|
72
72
|
disabled: {
|
73
73
|
type: Boolean,
|
74
|
-
default: false
|
74
|
+
default: false,
|
75
75
|
},
|
76
76
|
// 是否中读
|
77
77
|
readonly: {
|
78
78
|
type: Boolean,
|
79
|
-
default: false
|
79
|
+
default: false,
|
80
80
|
},
|
81
81
|
// 是否显示清除按钮
|
82
82
|
clearable: {
|
83
83
|
type: Boolean,
|
84
|
-
default: true
|
84
|
+
default: true,
|
85
85
|
},
|
86
86
|
// 校验规则
|
87
87
|
rules: {
|
88
88
|
type: Array,
|
89
|
-
default: () => []
|
89
|
+
default: () => [],
|
90
90
|
},
|
91
91
|
// 是否是示校验图标
|
92
92
|
verify: {
|
93
93
|
type: Boolean,
|
94
|
-
default: false
|
94
|
+
default: false,
|
95
95
|
},
|
96
96
|
prefix: {
|
97
97
|
type: Array as PropType<any[]>,
|
98
|
-
default: () => []
|
98
|
+
default: () => [],
|
99
99
|
},
|
100
100
|
suffix: {
|
101
101
|
type: Array as PropType<any[]>,
|
102
|
-
default: () => []
|
102
|
+
default: () => [],
|
103
103
|
},
|
104
104
|
rows: {
|
105
105
|
type: Number,
|
106
|
-
default: 3
|
107
|
-
}
|
106
|
+
default: 3,
|
107
|
+
},
|
108
108
|
});
|
109
109
|
|
110
110
|
const ready: any = ref(0);
|
@@ -164,7 +164,7 @@
|
|
164
164
|
(v: any) => {
|
165
165
|
mv.value = v;
|
166
166
|
},
|
167
|
-
{ deep: true, immediate: true }
|
167
|
+
{ deep: true, immediate: true },
|
168
168
|
);
|
169
169
|
|
170
170
|
watch(
|
@@ -180,7 +180,7 @@
|
|
180
180
|
// 自动高度
|
181
181
|
fAutoHeight();
|
182
182
|
},
|
183
|
-
{ deep: true }
|
183
|
+
{ deep: true },
|
184
184
|
);
|
185
185
|
|
186
186
|
onMounted(() => {
|
@@ -0,0 +1,275 @@
|
|
1
|
+
<template>
|
2
|
+
<div
|
3
|
+
:ui-form="`${theme} sz:${sz} ${state.error.co} type:textarea ${block ? ' :block' : ''} ${disabled ? 'disabled' : ''} ${readonly ? 'readonly' : ''}`"
|
4
|
+
@click="emits('click', $event)"
|
5
|
+
>
|
6
|
+
<div :ui-form-tips="state.error.ontips">{{ state.error.tips }}</div>
|
7
|
+
<div ui-form-prefix="">
|
8
|
+
<template v-for="(item, idx) in prefix" :key="idx">
|
9
|
+
<div v-if="isObject(item)" v-bind="item.attrs" v-on="event(item, props.modelValue)">
|
10
|
+
<div v-html="isFunction(item.value) ? item.value(props.modelValue) : item.value"></div>
|
11
|
+
</div>
|
12
|
+
<div v-else v-html="isFunction(item) ? item(props.modelValue) : item"></div>
|
13
|
+
</template>
|
14
|
+
<slot name="prefix"></slot>
|
15
|
+
</div>
|
16
|
+
<slot>
|
17
|
+
<textarea
|
18
|
+
ref="el"
|
19
|
+
:title="props.modelValue"
|
20
|
+
:value="props.modelValue"
|
21
|
+
:placeholder="placeholder"
|
22
|
+
:disabled="disabled"
|
23
|
+
:readonly="readonly"
|
24
|
+
:rows="rows"
|
25
|
+
ui-scroll=":y"
|
26
|
+
dir="auto"
|
27
|
+
@focus="emits('focus', $event, state)"
|
28
|
+
@input="input($event)"
|
29
|
+
@change="emits('change', $event, state)"
|
30
|
+
@blur="blur($event)"
|
31
|
+
></textarea>
|
32
|
+
</slot>
|
33
|
+
<div ui-form-suffix="">
|
34
|
+
<i ui-form-clean="" v-if="clearable && props.modelValue && !readonly && !disabled" @click.stop="clear"></i>
|
35
|
+
<slot name="suffix"></slot>
|
36
|
+
<template v-for="(item, idx) in suffix" :key="idx">
|
37
|
+
<div v-if="isObject(item)" v-bind="item.attrs" v-on="event(item, props.modelValue)">
|
38
|
+
<div v-html="isFunction(item.value) ? item.value(props.modelValue) : item.value"></div>
|
39
|
+
</div>
|
40
|
+
<div v-else v-html="isFunction(item) ? item(props.modelValue) : item"></div>
|
41
|
+
</template>
|
42
|
+
</div>
|
43
|
+
<i v-if="verify && state.interacted" :ui-form-verify="state.error.verify"></i>
|
44
|
+
</div>
|
45
|
+
</template>
|
46
|
+
|
47
|
+
<script setup lang="ts">
|
48
|
+
import { reactive, watch, ref, nextTick, onMounted } from 'vue';
|
49
|
+
import { isObject, isFunction } from '@fekit/utils';
|
50
|
+
|
51
|
+
const emits = defineEmits(['update:modelValue', 'click', 'blur', 'focus', 'change', 'input', 'clear']);
|
52
|
+
|
53
|
+
/**
|
54
|
+
* 入参说明
|
55
|
+
*
|
56
|
+
* modelValue 值
|
57
|
+
* theme 主题
|
58
|
+
* sz 尺寸
|
59
|
+
* co 颜色
|
60
|
+
* block 撑满
|
61
|
+
* ready 准备就绪
|
62
|
+
* tips 提示文案
|
63
|
+
* placeholder 内容占位
|
64
|
+
* maxlength 最大长度
|
65
|
+
* minlength 最小长度
|
66
|
+
* disabled 是否禁用
|
67
|
+
* readonly 是否只读
|
68
|
+
* clearable 是否显示清除按钮
|
69
|
+
* rules 校验规则
|
70
|
+
* verify 是否是示校验图标 2=tips 3=text 4=icon 5=tips+text 6=text+icon 7=text+icon
|
71
|
+
* prefix 前缀内容
|
72
|
+
* suffix 后缀内容
|
73
|
+
* interacted 用户是否交互
|
74
|
+
* autoHeight 是否自动调整高度
|
75
|
+
* rows 初始行数
|
76
|
+
*/
|
77
|
+
|
78
|
+
// 类型
|
79
|
+
interface Props {
|
80
|
+
modelValue?: string | number;
|
81
|
+
placeholder?: string;
|
82
|
+
rules?: Array<object>;
|
83
|
+
theme?: string;
|
84
|
+
sz?: '' | 'xs' | 's' | 'm' | 'l' | 'xl';
|
85
|
+
co?: string;
|
86
|
+
block?: boolean;
|
87
|
+
ready?: boolean;
|
88
|
+
tips?: string;
|
89
|
+
maxlength?: null | number;
|
90
|
+
minlength?: null | number;
|
91
|
+
disabled?: boolean;
|
92
|
+
readonly?: boolean;
|
93
|
+
clearable?: boolean;
|
94
|
+
verify?: boolean;
|
95
|
+
prefix?: Array<any>;
|
96
|
+
suffix?: Array<any>;
|
97
|
+
interacted?: boolean;
|
98
|
+
autoHeight?: boolean;
|
99
|
+
rows?: number;
|
100
|
+
}
|
101
|
+
const props: any = withDefaults(defineProps<Props>(), {
|
102
|
+
modelValue: '',
|
103
|
+
placeholder: '',
|
104
|
+
rules: () => [],
|
105
|
+
theme: '@a',
|
106
|
+
sz: '',
|
107
|
+
co: '',
|
108
|
+
block: true,
|
109
|
+
ready: false,
|
110
|
+
tips: '',
|
111
|
+
maxlength: null,
|
112
|
+
minlength: null,
|
113
|
+
disabled: false,
|
114
|
+
readonly: false,
|
115
|
+
clearable: true,
|
116
|
+
verify: false,
|
117
|
+
prefix: () => [],
|
118
|
+
suffix: () => [],
|
119
|
+
interacted: false,
|
120
|
+
// textarea 特有属性默认值
|
121
|
+
autoHeight: false,
|
122
|
+
rows: 3,
|
123
|
+
});
|
124
|
+
|
125
|
+
const state: any = reactive({
|
126
|
+
// 用户是否交互
|
127
|
+
interacted: false,
|
128
|
+
// 值
|
129
|
+
value: props.modelValue,
|
130
|
+
// 错误
|
131
|
+
error: {},
|
132
|
+
});
|
133
|
+
|
134
|
+
// textarea 元素引用
|
135
|
+
const el: any = ref(null);
|
136
|
+
|
137
|
+
// 自动高度功能
|
138
|
+
const fAutoHeight = () => {
|
139
|
+
nextTick(() => {
|
140
|
+
if (props.autoHeight && el.value) {
|
141
|
+
el.value.style.height = 'auto';
|
142
|
+
el.value.style.height = el.value.scrollHeight + 1 + 'px';
|
143
|
+
}
|
144
|
+
});
|
145
|
+
};
|
146
|
+
|
147
|
+
// 外部传入交互标识,主要用于外部没有输入但点击了提交
|
148
|
+
watch(
|
149
|
+
() => props.interacted,
|
150
|
+
(interacted: any) => {
|
151
|
+
if (interacted) {
|
152
|
+
state.interacted = interacted;
|
153
|
+
}
|
154
|
+
},
|
155
|
+
{ deep: true, immediate: true },
|
156
|
+
);
|
157
|
+
|
158
|
+
// 校验
|
159
|
+
watch(
|
160
|
+
[() => state.interacted, () => props.modelValue],
|
161
|
+
async () => {
|
162
|
+
if (state.interacted) {
|
163
|
+
// 提示文案
|
164
|
+
let tips = '';
|
165
|
+
// 错误类型
|
166
|
+
let type = '';
|
167
|
+
// 验证结果
|
168
|
+
let verify = '';
|
169
|
+
|
170
|
+
if (props.modelValue) {
|
171
|
+
// 有值
|
172
|
+
let hasError = false;
|
173
|
+
// 遍历校验规则
|
174
|
+
for (const rule of props.rules) {
|
175
|
+
if (rule && rule.validator) {
|
176
|
+
const yes = !(await rule.validator(props.modelValue));
|
177
|
+
if (yes) {
|
178
|
+
tips = rule.msg;
|
179
|
+
type = rule.type;
|
180
|
+
hasError = true;
|
181
|
+
break;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
185
|
+
verify = hasError ? 'no' : 'ok';
|
186
|
+
} else {
|
187
|
+
// 无值
|
188
|
+
let hasError = false;
|
189
|
+
// 遍历校验规则
|
190
|
+
for (const rule of props.rules) {
|
191
|
+
if (rule) {
|
192
|
+
tips = rule.msg;
|
193
|
+
type = rule.type;
|
194
|
+
if (rule.required) {
|
195
|
+
hasError = true;
|
196
|
+
break;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
verify = hasError ? 'no' : '';
|
201
|
+
}
|
202
|
+
if (verify !== 'no' && props.tips) {
|
203
|
+
tips = props.tips;
|
204
|
+
}
|
205
|
+
// 是否显示提示
|
206
|
+
const ontips = (verify === 'no' && tips) || props.tips ? 'show' : '';
|
207
|
+
// 状态颜色
|
208
|
+
const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
|
209
|
+
state.error = { tips, ontips, verify, co };
|
210
|
+
} else {
|
211
|
+
state.error = { tips: props.tips, ontips: props.tips ? 'show' : '', verify: '', co: '' };
|
212
|
+
}
|
213
|
+
},
|
214
|
+
{ deep: true, immediate: true },
|
215
|
+
);
|
216
|
+
|
217
|
+
// 清空
|
218
|
+
function clear() {
|
219
|
+
emits('update:modelValue', null);
|
220
|
+
emits('clear');
|
221
|
+
}
|
222
|
+
// 输入
|
223
|
+
const input = (e: any) => {
|
224
|
+
// 用户交互
|
225
|
+
if (!state.interacted) {
|
226
|
+
setTimeout(() => {
|
227
|
+
state.interacted = true;
|
228
|
+
}, 50);
|
229
|
+
}
|
230
|
+
|
231
|
+
// 长度限制
|
232
|
+
const value = e?.target?.value || '';
|
233
|
+
if (props.maxlength && value.length > props.maxlength) {
|
234
|
+
e.target.value = props.modelValue;
|
235
|
+
return false;
|
236
|
+
}
|
237
|
+
// 输入事件
|
238
|
+
emits('input', e, state);
|
239
|
+
emits('update:modelValue', value || null);
|
240
|
+
|
241
|
+
// 自动高度
|
242
|
+
fAutoHeight();
|
243
|
+
};
|
244
|
+
// 失焦
|
245
|
+
const blur = (e: any) => {
|
246
|
+
if (!state.interacted) {
|
247
|
+
setTimeout(() => {
|
248
|
+
state.interacted = true;
|
249
|
+
}, 50);
|
250
|
+
}
|
251
|
+
emits('blur', e, state);
|
252
|
+
};
|
253
|
+
|
254
|
+
// 事件处理
|
255
|
+
const event: any = (item: any, data: any): object => {
|
256
|
+
const _event: any = {};
|
257
|
+
if (isObject(item.event)) {
|
258
|
+
for (const key in item.event) {
|
259
|
+
const fun = item.event[key];
|
260
|
+
if (isFunction(fun)) {
|
261
|
+
_event[key] = (...args: any) => {
|
262
|
+
return fun({ data }, ...args);
|
263
|
+
};
|
264
|
+
}
|
265
|
+
}
|
266
|
+
}
|
267
|
+
return { ..._event };
|
268
|
+
};
|
269
|
+
|
270
|
+
// 组件挂载后初始化自动高度
|
271
|
+
onMounted(() => {
|
272
|
+
// 自动高度
|
273
|
+
fAutoHeight();
|
274
|
+
});
|
275
|
+
</script>
|
@@ -19,8 +19,8 @@
|
|
19
19
|
<div
|
20
20
|
ui-flex="col cm"
|
21
21
|
class="r-sm b-solid bk-none b-xs"
|
22
|
-
:class="`${item.isToday ? 'bk-main-ls' : item.isLastMonth || item.isNextMonth ? 'co-note' : item.isHoliday ? 'co-risk' : ''} ${
|
23
|
-
state.selected && state.selected === item.date ? 'active bg-main-ls co-fore' : 'hover-bg-weak'
|
22
|
+
:class="`${item.isToday ? 'bk-main-o-ls' : item.isLastMonth || item.isNextMonth ? 'co-note' : item.isHoliday ? 'co-risk' : ''} ${
|
23
|
+
state.selected && state.selected === item.date ? 'active bg-main-o-ls co-fore' : 'hover-bg-weak'
|
24
24
|
}`"
|
25
25
|
>
|
26
26
|
<span>{{ item.day }}</span>
|
@@ -107,40 +107,40 @@
|
|
107
107
|
// 提示文案
|
108
108
|
tips: {
|
109
109
|
type: String,
|
110
|
-
default: ''
|
110
|
+
default: '',
|
111
111
|
},
|
112
112
|
// 提示文案
|
113
113
|
placeholder: {
|
114
114
|
type: String,
|
115
|
-
default: ''
|
115
|
+
default: '',
|
116
116
|
},
|
117
117
|
// 格式
|
118
118
|
format: {
|
119
119
|
type: String,
|
120
|
-
default: ''
|
120
|
+
default: '',
|
121
121
|
},
|
122
122
|
// 值
|
123
123
|
value: {
|
124
124
|
type: [String, Number],
|
125
|
-
default: ''
|
125
|
+
default: '',
|
126
126
|
},
|
127
127
|
// 值
|
128
128
|
modelValue: { type: [String, Number], default: '' },
|
129
129
|
// 节假日
|
130
130
|
holiday: {
|
131
131
|
type: Object,
|
132
|
-
default: () => ({})
|
132
|
+
default: () => ({}),
|
133
133
|
},
|
134
134
|
// 校验规则
|
135
135
|
rules: {
|
136
136
|
type: Array,
|
137
|
-
default: () => []
|
137
|
+
default: () => [],
|
138
138
|
},
|
139
139
|
// 是否是示校验图标
|
140
140
|
verify: {
|
141
141
|
type: Boolean,
|
142
|
-
default: false
|
143
|
-
}
|
142
|
+
default: false,
|
143
|
+
},
|
144
144
|
});
|
145
145
|
|
146
146
|
// 内部数据
|
@@ -185,7 +185,7 @@
|
|
185
185
|
calendar.unshift({
|
186
186
|
date: `${last_y}-${numfill(last_m)}-${prevdays}`,
|
187
187
|
day: prevdays,
|
188
|
-
isLastMonth: 1
|
188
|
+
isLastMonth: 1,
|
189
189
|
});
|
190
190
|
prevdays = prevdays - 1;
|
191
191
|
}
|
@@ -196,7 +196,7 @@
|
|
196
196
|
day: _i,
|
197
197
|
isToday: curr_y === y && curr_m === m && curr_d === i,
|
198
198
|
isHoliday: props.holiday[`${y}-${numfill(m)}-${_i}`]?.name ? 1 : 0,
|
199
|
-
holiday: props.holiday[`${y}-${numfill(m)}-${_i}`]?.name
|
199
|
+
holiday: props.holiday[`${y}-${numfill(m)}-${_i}`]?.name,
|
200
200
|
});
|
201
201
|
}
|
202
202
|
for (let i = 1; calendar.length < 42; i++) {
|
@@ -204,14 +204,14 @@
|
|
204
204
|
calendar.push({
|
205
205
|
date: `${next_y}-${numfill(next_m)}-${_i}`,
|
206
206
|
day: _i,
|
207
|
-
isNextMonth: 1
|
207
|
+
isNextMonth: 1,
|
208
208
|
});
|
209
209
|
}
|
210
210
|
return { days: calendar, y, m, d };
|
211
211
|
}),
|
212
212
|
value: computed(() => {
|
213
213
|
return props.format ? idate(state.selected || props.value).format(props.format) : state.selected || props.value;
|
214
|
-
})
|
214
|
+
}),
|
215
215
|
});
|
216
216
|
const { curr = {} }: any = toRefs(state);
|
217
217
|
|