@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
@@ -54,7 +54,7 @@
|
|
54
54
|
// 用户是否交互
|
55
55
|
interacted: {
|
56
56
|
type: Boolean,
|
57
|
-
default: false
|
57
|
+
default: false,
|
58
58
|
},
|
59
59
|
theme: { type: String, default: '@a' },
|
60
60
|
sz: { type: String, default: 'm' },
|
@@ -63,42 +63,42 @@
|
|
63
63
|
// 提示文案
|
64
64
|
tips: {
|
65
65
|
type: String,
|
66
|
-
default: ''
|
66
|
+
default: '',
|
67
67
|
},
|
68
68
|
placeholder: {
|
69
69
|
type: String,
|
70
|
-
default: ''
|
70
|
+
default: '',
|
71
71
|
},
|
72
72
|
modelValue: {
|
73
73
|
type: Array as () => any[],
|
74
|
-
default: () => []
|
74
|
+
default: () => [],
|
75
75
|
},
|
76
76
|
options: {
|
77
77
|
type: Array as () => any[],
|
78
|
-
default: () => []
|
78
|
+
default: () => [],
|
79
79
|
},
|
80
80
|
ui: {
|
81
81
|
type: Object,
|
82
|
-
default: () => ({ sz: 'm' })
|
82
|
+
default: () => ({ sz: 'm' }),
|
83
83
|
},
|
84
84
|
// 校验规则
|
85
85
|
rules: {
|
86
86
|
type: Array,
|
87
|
-
default: () => []
|
87
|
+
default: () => [],
|
88
88
|
},
|
89
89
|
// 是否是示校验图标
|
90
90
|
verify: {
|
91
91
|
type: Boolean,
|
92
|
-
default: false
|
92
|
+
default: false,
|
93
93
|
},
|
94
94
|
tools: {
|
95
95
|
type: Boolean,
|
96
|
-
default: true
|
96
|
+
default: true,
|
97
97
|
},
|
98
98
|
spare: {
|
99
99
|
type: String,
|
100
|
-
default: '当前没有可选项'
|
101
|
-
}
|
100
|
+
default: '当前没有可选项',
|
101
|
+
},
|
102
102
|
});
|
103
103
|
const formName = new Date().getTime().toString();
|
104
104
|
|
@@ -129,7 +129,7 @@
|
|
129
129
|
}),
|
130
130
|
has: computed(() => {
|
131
131
|
return props.options?.some((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
|
132
|
-
})
|
132
|
+
}),
|
133
133
|
});
|
134
134
|
|
135
135
|
const toggle = () => {
|
@@ -144,7 +144,7 @@
|
|
144
144
|
verify: false,
|
145
145
|
prefix: () => [],
|
146
146
|
suffix: () => [],
|
147
|
-
interacted: false
|
147
|
+
interacted: false,
|
148
148
|
});
|
149
149
|
|
150
150
|
const change = ({ value = '' }: any = {}) => {
|
@@ -166,7 +166,7 @@
|
|
166
166
|
} else {
|
167
167
|
return props.options;
|
168
168
|
}
|
169
|
-
})
|
169
|
+
}),
|
170
170
|
});
|
171
171
|
// 选择
|
172
172
|
const select = (item: any = {}) => {
|
@@ -196,7 +196,7 @@
|
|
196
196
|
select,
|
197
197
|
remove,
|
198
198
|
change,
|
199
|
-
cancel
|
199
|
+
cancel,
|
200
200
|
});
|
201
201
|
</script>
|
202
202
|
. .
|
@@ -1,12 +1,15 @@
|
|
1
1
|
<template>
|
2
|
-
<div :ui-form="`@a type:select sz
|
2
|
+
<div :ui-form="`@a type:select${sz ? 'sz:' + sz : ''}`" :ui-form-open="state.show ? 'show' : ''">
|
3
3
|
<IFollowView ref="ifollow" tipBoxClass="ny-sm nx-no" tipBoxStyle="min-width: 100%" @onshow="onshow" @onhide="onhide">
|
4
4
|
<Input
|
5
5
|
v-bind="{ placeholder, rules, theme, sz, co, block, ready, type, tips, disabled, readonly: true, clearable: false, verify, prefix, suffix, interacted }"
|
6
|
-
v-model="state.
|
6
|
+
v-model="state.displayLabel"
|
7
7
|
:interacted="interacted"
|
8
8
|
>
|
9
|
-
<template #suffix
|
9
|
+
<template #suffix>
|
10
|
+
<i v-if="clearable && modelValue && !readonly && !disabled" ui-form-clean="" @click.stop="remove"></i>
|
11
|
+
<i ui-form-select=""></i>
|
12
|
+
</template>
|
10
13
|
</Input>
|
11
14
|
<template #tips v-if="!readonly && !disabled">
|
12
15
|
<div v-if="search" class="ny-sm nx-sl">
|
@@ -16,23 +19,39 @@
|
|
16
19
|
</template>
|
17
20
|
</Input>
|
18
21
|
</div>
|
19
|
-
<ul v-if="
|
22
|
+
<ul v-if="state.filter?.length" ui-scroll=":y s" class="nx-sm lh-sl" style="min-width: 100%; max-height: 16em">
|
20
23
|
<template v-for="(item, idx) of state.filter" :key="idx">
|
21
|
-
<li v-if="item.disabled" class="ux-hover nx-sm ny-ss r-ss o-ms nowrap" :class="item
|
24
|
+
<li v-if="item.disabled" class="ux-hover nx-sm ny-ss r-ss o-ms nowrap" :class="isItemSelected(item) ? 'co-main' : ''">
|
22
25
|
<del>{{ item.label || item }}</del>
|
23
26
|
</li>
|
24
|
-
<li v-else class="ux-hover nx-sm ny-ss r-ss nowrap" :class="item
|
27
|
+
<li v-else class="ux-hover nx-sm ny-ss r-ss nowrap" :class="isItemSelected(item) ? 'co-main' : ''" @click="select(item)">
|
25
28
|
<span>{{ item.label || item }}</span>
|
26
29
|
</li>
|
27
30
|
</template>
|
28
31
|
</ul>
|
29
32
|
<div v-else class="w-full ny-ms" ui-flex="col cm" v-html="spare"></div>
|
33
|
+
<!-- 其他选项输入框 -->
|
34
|
+
<div v-if="other && state.isInputting" class="nx-sm ny-sm">
|
35
|
+
<div class="o-mm" ui-line="@a"></div>
|
36
|
+
<div class="ny-sm">
|
37
|
+
<Input
|
38
|
+
v-model="customInputValue"
|
39
|
+
v-bind="other.config || {}"
|
40
|
+
:placeholder="other.config?.placeholder || '请输入自定义内容'"
|
41
|
+
sz="s"
|
42
|
+
@keyup.enter="confirmCustomInput"
|
43
|
+
@blur="confirmCustomInput"
|
44
|
+
ref="customInputRef"
|
45
|
+
/>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
|
30
49
|
<ul class="nx-sm lh-ml" v-if="tools">
|
31
50
|
<li class="my-ss"><div class="o-mm" ui-line="@a"></div></li>
|
32
51
|
<li ui-flex="row xm">
|
33
52
|
<div class="co-main">
|
34
53
|
<p class="nx-sm r-ss nowrap">
|
35
|
-
<span>{{ state.
|
54
|
+
<span>{{ state.availableCount }}个可选项</span>
|
36
55
|
</p>
|
37
56
|
</div>
|
38
57
|
<div>
|
@@ -46,12 +65,13 @@
|
|
46
65
|
</template>
|
47
66
|
|
48
67
|
<script setup lang="ts">
|
49
|
-
import { reactive, ref, computed } from 'vue';
|
68
|
+
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
50
69
|
import { Input } from '.';
|
51
70
|
import { IFollowView } from '../basic';
|
52
71
|
const ifollow: any = ref(null);
|
72
|
+
const customInputRef: any = ref(null);
|
53
73
|
|
54
|
-
const emits = defineEmits(['update:modelValue', 'change', 'onshow', 'onhide']);
|
74
|
+
const emits = defineEmits(['update:modelValue', 'change', 'onshow', 'onhide', 'update:other']);
|
55
75
|
|
56
76
|
/**
|
57
77
|
* 入参说明
|
@@ -86,8 +106,15 @@
|
|
86
106
|
|
87
107
|
// 类型
|
88
108
|
interface Props {
|
89
|
-
modelValue?: string | number;
|
109
|
+
modelValue?: string | number | null | boolean;
|
90
110
|
options: Array<object>;
|
111
|
+
all?: { label: string; value: null | '*' };
|
112
|
+
other?: {
|
113
|
+
value: string;
|
114
|
+
field?: string;
|
115
|
+
config?: object;
|
116
|
+
};
|
117
|
+
otherValue?: string;
|
91
118
|
tools?: boolean;
|
92
119
|
spare?: string;
|
93
120
|
search?: boolean;
|
@@ -119,7 +146,10 @@
|
|
119
146
|
const props: any = withDefaults(defineProps<Props>(), {
|
120
147
|
modelValue: '',
|
121
148
|
options: () => [],
|
122
|
-
|
149
|
+
all: undefined,
|
150
|
+
other: undefined,
|
151
|
+
otherValue: '',
|
152
|
+
tools: false,
|
123
153
|
spare: '当前没有可选项',
|
124
154
|
search: false,
|
125
155
|
pagination: false,
|
@@ -139,42 +169,218 @@
|
|
139
169
|
minlength: null,
|
140
170
|
disabled: false,
|
141
171
|
readonly: false,
|
142
|
-
clearable:
|
172
|
+
clearable: true,
|
143
173
|
verify: false,
|
144
174
|
prefix: () => [],
|
145
175
|
suffix: () => [],
|
146
|
-
interacted: false
|
176
|
+
interacted: false,
|
147
177
|
});
|
148
178
|
|
149
|
-
const change = (
|
179
|
+
const change = (value: any = null) => {
|
150
180
|
emits('update:modelValue', value);
|
151
181
|
emits('change', value);
|
152
182
|
};
|
153
183
|
|
184
|
+
// 自定义输入值
|
185
|
+
const customInputValue = ref('');
|
186
|
+
|
154
187
|
const state = reactive({
|
155
188
|
show: 0,
|
156
189
|
search: '',
|
190
|
+
isInputting: computed(() => {
|
191
|
+
// 如果配置了"其他"选项且当前选中的是"其他"
|
192
|
+
if (props.other) {
|
193
|
+
if (props.other.field) {
|
194
|
+
// 情况2:有独立字段,当主值匹配other.value且有otherValue时显示输入框
|
195
|
+
return props.modelValue === props.other.value && props.otherValue;
|
196
|
+
} else {
|
197
|
+
// 情况1:无独立字段,当值不在枚举中时显示输入框
|
198
|
+
if (props.modelValue && props.modelValue !== '') {
|
199
|
+
const isInEnum = props.options?.some((option: any) => `${option.value}` === `${props.modelValue}`);
|
200
|
+
return !isInEnum;
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
return false;
|
205
|
+
}),
|
157
206
|
selectd: computed(() => {
|
158
|
-
|
207
|
+
// 优先查找 all 选项
|
208
|
+
if (props.all && props.modelValue === props.all.value) {
|
209
|
+
return props.all;
|
210
|
+
}
|
211
|
+
// 查找普通选项
|
212
|
+
const found = props?.options?.find((option: any) => `${option.value}` === `${props.modelValue}`);
|
213
|
+
if (found) {
|
214
|
+
// 如果是分字段存储模式且选中的是other选项,需要显示自定义值
|
215
|
+
if (props.other?.field && found.value === props.other.value && props.otherValue) {
|
216
|
+
const otherLabel = found.label || '其他';
|
217
|
+
return {
|
218
|
+
label: `${otherLabel}-${props.otherValue}`,
|
219
|
+
value: found.value,
|
220
|
+
};
|
221
|
+
}
|
222
|
+
return found;
|
223
|
+
}
|
224
|
+
|
225
|
+
// 如果配置了 other 且当前值不在枚举中,可能是自定义输入值(直接存储模式)
|
226
|
+
if (props.other && props.modelValue && !props.other.field) {
|
227
|
+
// 找到其他选项的label
|
228
|
+
const otherOption = props?.options?.find((option: any) => `${option.value}` === `${props.other.value}`);
|
229
|
+
const otherLabel = otherOption?.label || '其他';
|
230
|
+
return {
|
231
|
+
label: `${otherLabel}-${props.modelValue}`,
|
232
|
+
value: props.modelValue,
|
233
|
+
};
|
234
|
+
}
|
235
|
+
|
236
|
+
return {};
|
237
|
+
}),
|
238
|
+
displayLabel: computed(() => {
|
239
|
+
return state.selectd.label || '';
|
240
|
+
}),
|
241
|
+
availableCount: computed(() => {
|
242
|
+
return state.filter?.filter((item: any) => !item.disabled)?.length || 0;
|
159
243
|
}),
|
160
244
|
filter: computed(() => {
|
245
|
+
let filteredOptions = props.options || [];
|
246
|
+
|
161
247
|
if (state.search) {
|
162
|
-
|
248
|
+
filteredOptions = filteredOptions.filter((item: any) => {
|
163
249
|
return item.label?.includes(state.search);
|
164
250
|
});
|
165
|
-
} else {
|
166
|
-
return props.options;
|
167
251
|
}
|
168
|
-
|
252
|
+
|
253
|
+
// 在顶部添加全部选项
|
254
|
+
if (props.all) {
|
255
|
+
filteredOptions = [props.all, ...filteredOptions];
|
256
|
+
}
|
257
|
+
|
258
|
+
return filteredOptions;
|
259
|
+
}),
|
169
260
|
});
|
261
|
+
|
262
|
+
// 同步自定义输入值
|
263
|
+
watch(
|
264
|
+
[() => props.modelValue, () => props.otherValue, () => props.other, () => props.options],
|
265
|
+
() => {
|
266
|
+
if (props.other) {
|
267
|
+
if (props.other.field) {
|
268
|
+
// 情况2:有独立字段,显示otherValue
|
269
|
+
customInputValue.value = props.otherValue || '';
|
270
|
+
} else {
|
271
|
+
// 情况1:无独立字段,显示当前modelValue(如果不在枚举中)
|
272
|
+
if (props.modelValue && props.modelValue !== '') {
|
273
|
+
const isInEnum = props.options?.some((option: any) => `${option.value}` === `${props.modelValue}`);
|
274
|
+
customInputValue.value = !isInEnum ? props.modelValue : '';
|
275
|
+
} else {
|
276
|
+
customInputValue.value = '';
|
277
|
+
}
|
278
|
+
}
|
279
|
+
} else {
|
280
|
+
customInputValue.value = '';
|
281
|
+
}
|
282
|
+
},
|
283
|
+
{ immediate: true },
|
284
|
+
);
|
285
|
+
|
286
|
+
// 监听并验证modelValue的有效性
|
287
|
+
watch(
|
288
|
+
[() => props.modelValue, () => props.options, () => props.all, () => props.other],
|
289
|
+
([value, options, allOption, otherConfig]) => {
|
290
|
+
// 如果配置了 other,则允许任意值(可能是用户自定义输入)
|
291
|
+
if (otherConfig) {
|
292
|
+
return;
|
293
|
+
}
|
294
|
+
|
295
|
+
// 如果有值但不在有效选项中,清空该值
|
296
|
+
if (value != null && value !== '' && options?.length > 0) {
|
297
|
+
let isValid = false;
|
298
|
+
|
299
|
+
// 检查是否是 all 选项
|
300
|
+
if (allOption && value === allOption.value) {
|
301
|
+
isValid = true;
|
302
|
+
} else {
|
303
|
+
// 检查是否在普通选项中
|
304
|
+
isValid = options.some((option: any) => `${option.value}` === `${value}`);
|
305
|
+
}
|
306
|
+
|
307
|
+
if (!isValid) {
|
308
|
+
nextTick(() => {
|
309
|
+
change(null);
|
310
|
+
});
|
311
|
+
}
|
312
|
+
}
|
313
|
+
},
|
314
|
+
{ immediate: true },
|
315
|
+
);
|
316
|
+
|
170
317
|
// 选择
|
171
318
|
const select = (item: any = {}) => {
|
172
|
-
|
173
|
-
|
319
|
+
if (props.other && item.value === props.other.value) {
|
320
|
+
// 选中"其他"选项时,设置值并聚焦输入框
|
321
|
+
if (props.other.field) {
|
322
|
+
change(props.other.value);
|
323
|
+
emits('update:other', '');
|
324
|
+
} else {
|
325
|
+
change('');
|
326
|
+
}
|
327
|
+
customInputValue.value = '';
|
328
|
+
nextTick(() => {
|
329
|
+
customInputRef.value?.focus();
|
330
|
+
});
|
331
|
+
} else {
|
332
|
+
change(item.value);
|
333
|
+
ifollow.value.cancel();
|
334
|
+
}
|
335
|
+
};
|
336
|
+
|
337
|
+
// 确认自定义输入
|
338
|
+
const confirmCustomInput = () => {
|
339
|
+
if (customInputValue.value.trim()) {
|
340
|
+
if (props.other?.field) {
|
341
|
+
// 如果指定了 field,则主字段存储选项值,field 存储自定义输入
|
342
|
+
change(props.other.value);
|
343
|
+
emits('update:other', customInputValue.value.trim());
|
344
|
+
} else {
|
345
|
+
// 如果没有指定 field,则直接在主字段存储自定义输入
|
346
|
+
change(customInputValue.value.trim());
|
347
|
+
}
|
348
|
+
ifollow.value.cancel();
|
349
|
+
} else {
|
350
|
+
// 如果输入为空,清空值
|
351
|
+
change(null);
|
352
|
+
if (props.other?.field) {
|
353
|
+
emits('update:other', '');
|
354
|
+
}
|
355
|
+
}
|
356
|
+
};
|
357
|
+
|
358
|
+
// 判断选项是否被选中(包括"其他"选项的特殊逻辑)
|
359
|
+
const isItemSelected = (item: any) => {
|
360
|
+
// 普通选项的判断
|
361
|
+
if (item.value === state.selectd?.value) {
|
362
|
+
return true;
|
363
|
+
}
|
364
|
+
|
365
|
+
// "其他"选项的特殊判断
|
366
|
+
if (props.other && item.value === props.other.value) {
|
367
|
+
if (props.other.field) {
|
368
|
+
// 情况2:有独立字段,当主值匹配other.value时高亮
|
369
|
+
return props.modelValue === props.other.value;
|
370
|
+
} else {
|
371
|
+
// 情况1:无独立字段,当值不在枚举中时高亮
|
372
|
+
if (props.modelValue && props.modelValue !== '') {
|
373
|
+
const isInEnum = props.options?.some((option: any) => `${option.value}` === `${props.modelValue}`);
|
374
|
+
return !isInEnum;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
return false;
|
174
380
|
};
|
175
381
|
// 清空
|
176
382
|
const remove = () => {
|
177
|
-
change(
|
383
|
+
change(null);
|
178
384
|
ifollow.value.cancel();
|
179
385
|
};
|
180
386
|
// 取消
|
@@ -195,7 +401,7 @@
|
|
195
401
|
select,
|
196
402
|
remove,
|
197
403
|
change,
|
198
|
-
cancel
|
404
|
+
cancel,
|
199
405
|
});
|
200
406
|
</script>
|
201
407
|
. .
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<template>
|
2
2
|
<ul v-if="props.options?.length" class="my-sm-sub lh-ss">
|
3
3
|
<li
|
4
|
-
class="hover:bg-main-ss n-sl r-ss b-solid b-xs"
|
5
|
-
:class="`${item.value === mv ? 'bk-main-ml bg-main-ss' : 'bk-case'}`"
|
4
|
+
class="hover:bg-main-o-ss n-sl r-ss b-solid b-xs"
|
5
|
+
:class="`${item.value === mv ? 'bk-main-o-ml bg-main-o-ss' : 'bk-case'}`"
|
6
6
|
v-for="(item, idx) of props.options"
|
7
7
|
:key="idx"
|
8
8
|
@click="mv = item.value === mv ? '' : item.value"
|
@@ -27,16 +27,16 @@
|
|
27
27
|
placeholder: { type: String, default: '' },
|
28
28
|
options: {
|
29
29
|
type: Array as () => any[],
|
30
|
-
default: () => []
|
30
|
+
default: () => [],
|
31
31
|
},
|
32
32
|
modelValue: {
|
33
33
|
type: [String, Number],
|
34
|
-
default: ''
|
34
|
+
default: '',
|
35
35
|
},
|
36
36
|
rules: {
|
37
37
|
type: Array,
|
38
|
-
default: () => []
|
39
|
-
}
|
38
|
+
default: () => [],
|
39
|
+
},
|
40
40
|
});
|
41
41
|
|
42
42
|
// eslint-disable-next-line vue/no-dupe-keys
|
@@ -47,12 +47,12 @@
|
|
47
47
|
() => props.modelValue,
|
48
48
|
(value: any) => {
|
49
49
|
mv.value = value;
|
50
|
-
}
|
50
|
+
},
|
51
51
|
);
|
52
52
|
watch(
|
53
53
|
() => mv.value,
|
54
54
|
(value: any) => {
|
55
55
|
emits('update:modelValue', value);
|
56
|
-
}
|
56
|
+
},
|
57
57
|
);
|
58
58
|
</script>
|
@@ -43,16 +43,16 @@
|
|
43
43
|
placeholder: { type: String, default: '' },
|
44
44
|
options: {
|
45
45
|
type: Array as () => any[],
|
46
|
-
default: () => []
|
46
|
+
default: () => [],
|
47
47
|
},
|
48
48
|
modelValue: {
|
49
49
|
type: [String, Number],
|
50
|
-
default: ''
|
50
|
+
default: '',
|
51
51
|
},
|
52
52
|
rules: {
|
53
53
|
type: Array,
|
54
|
-
default: () => []
|
55
|
-
}
|
54
|
+
default: () => [],
|
55
|
+
},
|
56
56
|
});
|
57
57
|
// 内部数据
|
58
58
|
const mv: any = ref(props.modelValue);
|
@@ -61,7 +61,7 @@
|
|
61
61
|
(v: any) => {
|
62
62
|
mv.value = v;
|
63
63
|
},
|
64
|
-
{ deep: true, immediate: true }
|
64
|
+
{ deep: true, immediate: true },
|
65
65
|
);
|
66
66
|
const state = reactive({
|
67
67
|
view: 0,
|
@@ -74,7 +74,7 @@
|
|
74
74
|
}
|
75
75
|
}
|
76
76
|
return _value;
|
77
|
-
})
|
77
|
+
}),
|
78
78
|
});
|
79
79
|
// 更新
|
80
80
|
const change = ({ value = null }: any = {}) => {
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div v-if="props.options?.length" class="mr-sm-sub mb-sm-sub">
|
3
3
|
<span
|
4
4
|
class="lh-ss ny-sm nx-ms r-xl dib"
|
5
|
-
:class="`${mv == item.value ? 'bg-main-sm co-main' : 'bg-weak'}`"
|
5
|
+
:class="`${mv == item.value ? 'bg-main-o-sm co-main' : 'bg-weak'}`"
|
6
6
|
v-for="(item, idx) of props.options"
|
7
7
|
:key="idx"
|
8
8
|
@click="mv = item.value === mv ? '' : item.value"
|
@@ -24,16 +24,16 @@
|
|
24
24
|
placeholder: { type: String, default: '' },
|
25
25
|
options: {
|
26
26
|
type: Array as () => any[],
|
27
|
-
default: () => []
|
27
|
+
default: () => [],
|
28
28
|
},
|
29
29
|
modelValue: {
|
30
30
|
type: [String, Number],
|
31
|
-
default: ''
|
31
|
+
default: '',
|
32
32
|
},
|
33
33
|
rules: {
|
34
34
|
type: Array,
|
35
|
-
default: () => []
|
36
|
-
}
|
35
|
+
default: () => [],
|
36
|
+
},
|
37
37
|
});
|
38
38
|
// 内部数据
|
39
39
|
const mv: any = ref(props.modelValue);
|
@@ -41,12 +41,12 @@
|
|
41
41
|
() => props.modelValue,
|
42
42
|
(value: any) => {
|
43
43
|
mv.value = value;
|
44
|
-
}
|
44
|
+
},
|
45
45
|
);
|
46
46
|
watch(
|
47
47
|
() => mv.value,
|
48
48
|
(value: any) => {
|
49
49
|
emits('update:modelValue', value);
|
50
|
-
}
|
50
|
+
},
|
51
51
|
);
|
52
52
|
</script>
|
@@ -144,7 +144,7 @@
|
|
144
144
|
verify: false,
|
145
145
|
prefix: () => [],
|
146
146
|
suffix: () => [],
|
147
|
-
interacted: false
|
147
|
+
interacted: false,
|
148
148
|
});
|
149
149
|
|
150
150
|
const state: any = reactive({
|
@@ -158,7 +158,7 @@
|
|
158
158
|
return (props.chain ? _item.chain : _item.label) || '';
|
159
159
|
}),
|
160
160
|
filter: [],
|
161
|
-
value: ''
|
161
|
+
value: '',
|
162
162
|
});
|
163
163
|
watch(
|
164
164
|
() => state.value,
|
@@ -167,7 +167,7 @@
|
|
167
167
|
change(value);
|
168
168
|
}
|
169
169
|
},
|
170
|
-
{ deep: true }
|
170
|
+
{ deep: true },
|
171
171
|
);
|
172
172
|
watch(
|
173
173
|
[() => state.search, () => props.options],
|
@@ -178,7 +178,7 @@
|
|
178
178
|
state.filter = props.options;
|
179
179
|
}
|
180
180
|
},
|
181
|
-
{ deep: true, immediate: true }
|
181
|
+
{ deep: true, immediate: true },
|
182
182
|
);
|
183
183
|
|
184
184
|
const change = (value: any = '') => {
|
@@ -221,7 +221,7 @@
|
|
221
221
|
select,
|
222
222
|
remove,
|
223
223
|
change,
|
224
|
-
cancel
|
224
|
+
cancel,
|
225
225
|
});
|
226
226
|
</script>
|
227
227
|
.. ..
|