@neatui/vue 2.17.2 → 2.17.5
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/basic/IScrollView.vue +115 -110
- 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.vue +227 -147
- package/src/components/form/index.ts +5 -3
- package/src/components/loader/FormLoader/FormLoader.vue +422 -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@v2.vue +0 -275
- 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
|
@@ -1,192 +1,272 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:ui-form="`${theme} sz:${sz} ${state.co} type:textarea ${block ? ' :block' : ''} ${disabled ? 'disabled' : ''} ${readonly ? 'readonly' : ''}`"
|
|
3
|
+
:ui-form="`${theme} sz:${sz} ${state.error.co} type:textarea ${block ? ' :block' : ''} ${disabled ? 'disabled' : ''} ${readonly ? 'readonly' : ''}`"
|
|
4
4
|
@click="emits('click', $event)"
|
|
5
5
|
>
|
|
6
|
-
<div
|
|
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>
|
|
7
16
|
<slot>
|
|
8
17
|
<textarea
|
|
9
18
|
ref="el"
|
|
10
|
-
:
|
|
11
|
-
|
|
12
|
-
:type="type"
|
|
19
|
+
:title="props.modelValue"
|
|
20
|
+
:value="props.modelValue"
|
|
13
21
|
:placeholder="placeholder"
|
|
14
|
-
:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@change="emits('change', $event)"
|
|
18
|
-
@blur="emits('blur', $event)"
|
|
22
|
+
:disabled="disabled"
|
|
23
|
+
:readonly="readonly"
|
|
24
|
+
:rows="rows"
|
|
19
25
|
ui-scroll=":y"
|
|
20
26
|
dir="auto"
|
|
27
|
+
@focus="emits('focus', $event, state)"
|
|
28
|
+
@input="input($event)"
|
|
29
|
+
@change="emits('change', $event, state)"
|
|
30
|
+
@blur="blur($event)"
|
|
21
31
|
></textarea>
|
|
22
32
|
</slot>
|
|
23
|
-
<
|
|
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>
|
|
24
44
|
</div>
|
|
25
45
|
</template>
|
|
26
46
|
|
|
27
47
|
<script setup lang="ts">
|
|
28
|
-
import {
|
|
48
|
+
import { reactive, watch, ref, nextTick, onMounted } from 'vue';
|
|
49
|
+
import { isObject, isFunction } from '@fekit/utils';
|
|
29
50
|
|
|
30
51
|
const emits = defineEmits(['update:modelValue', 'click', 'blur', 'focus', 'change', 'input', 'clear']);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
prefix:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
default: () => [],
|
|
103
|
-
},
|
|
104
|
-
rows: {
|
|
105
|
-
type: Number,
|
|
106
|
-
default: 3,
|
|
107
|
-
},
|
|
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,
|
|
108
123
|
});
|
|
109
124
|
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// 验证结果
|
|
118
|
-
let verify = '';
|
|
119
|
-
if (props.modelValue) {
|
|
120
|
-
// 有值
|
|
121
|
-
const res: any = props.rules?.some((rule: any) => {
|
|
122
|
-
const yes = rule.validator && !rule.validator(props.modelValue);
|
|
123
|
-
tips = rule.msg;
|
|
124
|
-
type = rule.type;
|
|
125
|
-
return yes;
|
|
126
|
-
});
|
|
127
|
-
verify = res ? 'no' : 'ok';
|
|
128
|
-
} else {
|
|
129
|
-
// 无值
|
|
130
|
-
const res: any = props.rules?.some((rule: any) => {
|
|
131
|
-
tips = rule.msg;
|
|
132
|
-
type = rule.type;
|
|
133
|
-
return rule.required;
|
|
134
|
-
});
|
|
135
|
-
verify = res ? 'no' : '';
|
|
136
|
-
}
|
|
137
|
-
if (verify !== 'no' && props.tips) {
|
|
138
|
-
tips = props.tips;
|
|
139
|
-
}
|
|
140
|
-
// 是否显示提示
|
|
141
|
-
const ontips = verify === 'no' && tips ? 'show' : '';
|
|
142
|
-
// 状态颜色
|
|
143
|
-
const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
|
|
144
|
-
return { tips, ontips, verify, co };
|
|
145
|
-
} else {
|
|
146
|
-
return {};
|
|
147
|
-
}
|
|
125
|
+
const state: any = reactive({
|
|
126
|
+
// 用户是否交互
|
|
127
|
+
interacted: false,
|
|
128
|
+
// 值
|
|
129
|
+
value: props.modelValue,
|
|
130
|
+
// 错误
|
|
131
|
+
error: {},
|
|
148
132
|
});
|
|
149
133
|
|
|
150
|
-
//
|
|
134
|
+
// textarea 元素引用
|
|
151
135
|
const el: any = ref(null);
|
|
136
|
+
|
|
137
|
+
// 自动高度功能
|
|
152
138
|
const fAutoHeight = () => {
|
|
153
139
|
nextTick(() => {
|
|
154
|
-
if (props.autoHeight) {
|
|
140
|
+
if (props.autoHeight && el.value) {
|
|
155
141
|
el.value.style.height = 'auto';
|
|
156
142
|
el.value.style.height = el.value.scrollHeight + 1 + 'px';
|
|
157
143
|
}
|
|
158
144
|
});
|
|
159
145
|
};
|
|
160
146
|
|
|
161
|
-
|
|
147
|
+
// 外部传入交互标识,主要用于外部没有输入但点击了提交
|
|
162
148
|
watch(
|
|
163
|
-
() => props.
|
|
164
|
-
(
|
|
165
|
-
|
|
149
|
+
() => props.interacted,
|
|
150
|
+
(interacted: any) => {
|
|
151
|
+
state.interacted = interacted;
|
|
166
152
|
},
|
|
167
153
|
{ deep: true, immediate: true },
|
|
168
154
|
);
|
|
169
155
|
|
|
156
|
+
// 校验
|
|
170
157
|
watch(
|
|
171
|
-
() =>
|
|
172
|
-
(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
158
|
+
[() => state.interacted, () => props.modelValue],
|
|
159
|
+
async () => {
|
|
160
|
+
if (state.interacted) {
|
|
161
|
+
// 提示文案
|
|
162
|
+
let tips = '';
|
|
163
|
+
// 错误类型
|
|
164
|
+
let type = '';
|
|
165
|
+
// 验证结果
|
|
166
|
+
let verify = '';
|
|
179
167
|
|
|
180
|
-
|
|
181
|
-
|
|
168
|
+
if (props.modelValue) {
|
|
169
|
+
// 有值
|
|
170
|
+
let hasError = false;
|
|
171
|
+
// 遍历校验规则
|
|
172
|
+
for (const rule of props.rules) {
|
|
173
|
+
if (rule && rule.validator) {
|
|
174
|
+
const yes = !(await rule.validator(props.modelValue));
|
|
175
|
+
if (yes) {
|
|
176
|
+
tips = rule.msg;
|
|
177
|
+
type = rule.type;
|
|
178
|
+
hasError = true;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
verify = hasError ? 'no' : 'ok';
|
|
184
|
+
} else {
|
|
185
|
+
// 无值
|
|
186
|
+
let hasError = false;
|
|
187
|
+
// 遍历校验规则
|
|
188
|
+
for (const rule of props.rules) {
|
|
189
|
+
if (rule) {
|
|
190
|
+
tips = rule.msg;
|
|
191
|
+
type = rule.type;
|
|
192
|
+
if (rule.required) {
|
|
193
|
+
hasError = true;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
verify = hasError ? 'no' : '';
|
|
199
|
+
}
|
|
200
|
+
if (verify !== 'no' && props.tips) {
|
|
201
|
+
tips = props.tips;
|
|
202
|
+
}
|
|
203
|
+
// 是否显示提示
|
|
204
|
+
const ontips = (verify === 'no' && tips) || props.tips ? 'show' : '';
|
|
205
|
+
// 状态颜色
|
|
206
|
+
const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
|
|
207
|
+
state.error = { tips, ontips, verify, co };
|
|
208
|
+
} else {
|
|
209
|
+
state.error = { tips: props.tips, ontips: props.tips ? 'show' : '', verify: '', co: '' };
|
|
210
|
+
}
|
|
182
211
|
},
|
|
183
|
-
{ deep: true },
|
|
212
|
+
{ deep: true, immediate: true },
|
|
184
213
|
);
|
|
185
214
|
|
|
215
|
+
// 清空
|
|
216
|
+
function clear() {
|
|
217
|
+
emits('update:modelValue', null);
|
|
218
|
+
emits('clear');
|
|
219
|
+
}
|
|
220
|
+
// 输入
|
|
221
|
+
const input = (e: any) => {
|
|
222
|
+
// 用户交互
|
|
223
|
+
if (!state.interacted) {
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
state.interacted = true;
|
|
226
|
+
}, 50);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 长度限制
|
|
230
|
+
const value = e?.target?.value || '';
|
|
231
|
+
if (props.maxlength && value.length > props.maxlength) {
|
|
232
|
+
e.target.value = props.modelValue;
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
// 输入事件
|
|
236
|
+
emits('input', e, state);
|
|
237
|
+
emits('update:modelValue', value || null);
|
|
238
|
+
|
|
239
|
+
// 自动高度
|
|
240
|
+
fAutoHeight();
|
|
241
|
+
};
|
|
242
|
+
// 失焦
|
|
243
|
+
const blur = (e: any) => {
|
|
244
|
+
if (!state.interacted) {
|
|
245
|
+
setTimeout(() => {
|
|
246
|
+
state.interacted = true;
|
|
247
|
+
}, 50);
|
|
248
|
+
}
|
|
249
|
+
emits('blur', e, state);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// 事件处理
|
|
253
|
+
const event: any = (item: any, data: any): object => {
|
|
254
|
+
const _event: any = {};
|
|
255
|
+
if (isObject(item.event)) {
|
|
256
|
+
for (const key in item.event) {
|
|
257
|
+
const fun = item.event[key];
|
|
258
|
+
if (isFunction(fun)) {
|
|
259
|
+
_event[key] = (...args: any) => {
|
|
260
|
+
return fun({ data }, ...args);
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return { ..._event };
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// 组件挂载后初始化自动高度
|
|
186
269
|
onMounted(() => {
|
|
187
|
-
setTimeout(() => {
|
|
188
|
-
ready.value = 1;
|
|
189
|
-
}, 300);
|
|
190
270
|
// 自动高度
|
|
191
271
|
fAutoHeight();
|
|
192
272
|
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Input from './Input@v3.vue';
|
|
2
2
|
import InputRange from './InputRange.vue';
|
|
3
3
|
import Switch from './Switch.vue';
|
|
4
|
-
import Textarea from './Textarea
|
|
4
|
+
import Textarea from './Textarea.vue';
|
|
5
5
|
|
|
6
6
|
import Checkbox from './Checkbox.vue';
|
|
7
|
+
import CheckboxItem from './CheckboxItem.vue';
|
|
8
|
+
import CheckboxGroup from './CheckboxGroup.vue';
|
|
7
9
|
import Select from './Select@v3.vue';
|
|
8
10
|
import SelectList from './SelectList.vue';
|
|
9
11
|
import SelectTags from './SelectTags.vue';
|
|
@@ -17,8 +19,6 @@ import SearchMoreSelect from './SearchMoreSelect.vue';
|
|
|
17
19
|
import PageSelect from './PageSelect.vue';
|
|
18
20
|
import SelectTree from './SelectTree/SelectTree@v1.vue';
|
|
19
21
|
|
|
20
|
-
// import DateView from './DateView.vue';
|
|
21
|
-
// import DateView from './DateView@v2.vue';
|
|
22
22
|
import DateView from './DateView@v3.vue';
|
|
23
23
|
import DateRangeView from './DateRangeView@v3.vue';
|
|
24
24
|
import DatePicker from './DatePicker.vue';
|
|
@@ -34,6 +34,8 @@ export {
|
|
|
34
34
|
Switch,
|
|
35
35
|
Textarea,
|
|
36
36
|
Checkbox,
|
|
37
|
+
CheckboxItem,
|
|
38
|
+
CheckboxGroup,
|
|
37
39
|
Select,
|
|
38
40
|
SelectList,
|
|
39
41
|
SelectTags,
|