@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,13 +1,13 @@
|
|
1
1
|
<template>
|
2
2
|
<div ui-flex="row" class="mc-upload">
|
3
3
|
<template v-if="files && files.length > 0">
|
4
|
-
<
|
5
|
-
<template #
|
4
|
+
<IDraggable v-model:lists="files" @update:lists="update" class="mc-upload-img">
|
5
|
+
<template #default="{ item: element, idx: index }">
|
6
6
|
<div class="mc-upload-img-item">
|
7
7
|
<Image :src="element" :files="files" :initialSlide="index" v-bind="$attrs" @delImg="delImg" />
|
8
8
|
</div>
|
9
9
|
</template>
|
10
|
-
</
|
10
|
+
</IDraggable>
|
11
11
|
</template>
|
12
12
|
<template v-if="(!multiple && files && files.length === 0) || (multiple && (!limit || (limit && files && files.length < limit)))">
|
13
13
|
<slot>
|
@@ -33,7 +33,7 @@
|
|
33
33
|
<script setup lang="ts">
|
34
34
|
import { ref, watch } from 'vue';
|
35
35
|
import { Image, PhotoEditor } from '../display';
|
36
|
-
import
|
36
|
+
import IDraggable from '../basic/IDraggable.vue';
|
37
37
|
import Compressor from 'compressorjs';
|
38
38
|
import { Layer, LayerById } from '../basic';
|
39
39
|
import { isArray } from '@fekit/utils';
|
@@ -63,7 +63,7 @@
|
|
63
63
|
accept: 'image/*',
|
64
64
|
multiple: false,
|
65
65
|
crop: false,
|
66
|
-
action: '/common/updateFile'
|
66
|
+
action: '/common/updateFile',
|
67
67
|
});
|
68
68
|
|
69
69
|
const emit = defineEmits(['update:modelValue', 'change']);
|
@@ -104,7 +104,7 @@
|
|
104
104
|
success: resolve,
|
105
105
|
maxWidth: 1000,
|
106
106
|
maxHeight: 700,
|
107
|
-
error: reject
|
107
|
+
error: reject,
|
108
108
|
});
|
109
109
|
});
|
110
110
|
const { name = '' }: any = _blob || {};
|
@@ -132,7 +132,7 @@
|
|
132
132
|
emit('update:modelValue', isArray(props.modelValue) ? files.value : files.value.length > 0 ? files.value[0].imgUrl : '');
|
133
133
|
}
|
134
134
|
},
|
135
|
-
{ deep: true }
|
135
|
+
{ deep: true },
|
136
136
|
);
|
137
137
|
|
138
138
|
defineExpose({ change, uploadClick });
|
@@ -113,7 +113,7 @@
|
|
113
113
|
verify: false,
|
114
114
|
prefix: () => [],
|
115
115
|
suffix: () => [],
|
116
|
-
interacted: false
|
116
|
+
interacted: false,
|
117
117
|
});
|
118
118
|
|
119
119
|
const state: any = reactive({
|
@@ -122,7 +122,7 @@
|
|
122
122
|
// 值
|
123
123
|
value: props.modelValue,
|
124
124
|
// 错误
|
125
|
-
error: {}
|
125
|
+
error: {},
|
126
126
|
});
|
127
127
|
// 外部传入交互标识,主要用于外部没有输入但点击了提交
|
128
128
|
watch(
|
@@ -132,7 +132,7 @@
|
|
132
132
|
state.interacted = interacted;
|
133
133
|
}
|
134
134
|
},
|
135
|
-
{ deep: true, immediate: true }
|
135
|
+
{ deep: true, immediate: true },
|
136
136
|
);
|
137
137
|
|
138
138
|
// 监听外部数据
|
@@ -207,12 +207,12 @@
|
|
207
207
|
state.error = { tips: props.tips, ontips: props.tips ? 'show' : '', verify: '', co: '' };
|
208
208
|
}
|
209
209
|
},
|
210
|
-
{ deep: true, immediate: true }
|
210
|
+
{ deep: true, immediate: true },
|
211
211
|
);
|
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,7 +57,7 @@
|
|
50
57
|
</template>
|
51
58
|
|
52
59
|
<script setup lang="ts">
|
53
|
-
import { reactive, ref, computed, watch } from 'vue';
|
60
|
+
import { reactive, ref, computed, watch, nextTick } from 'vue';
|
54
61
|
import { Input } from '.';
|
55
62
|
import { IFollowView } from '../basic';
|
56
63
|
const ifollow: any = ref(null);
|
@@ -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: '',
|
@@ -139,7 +148,7 @@
|
|
139
148
|
verify: false,
|
140
149
|
prefix: () => [],
|
141
150
|
suffix: () => [],
|
142
|
-
interacted: false
|
151
|
+
interacted: false,
|
143
152
|
});
|
144
153
|
// 内部数据
|
145
154
|
const state: any = reactive({
|
@@ -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
|
156
|
-
})
|
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
|
+
}
|
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
|
-
{ deep: true, immediate: true }
|
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
|
>
|
@@ -29,23 +29,23 @@
|
|
29
29
|
placeholder: { type: String, default: '' },
|
30
30
|
modelValue: {
|
31
31
|
type: Array as () => any[],
|
32
|
-
default: () => []
|
32
|
+
default: () => [],
|
33
33
|
},
|
34
34
|
options: {
|
35
35
|
type: Array as () => any[],
|
36
|
-
default: () => []
|
36
|
+
default: () => [],
|
37
37
|
},
|
38
38
|
rules: {
|
39
39
|
type: Array,
|
40
|
-
default: () => []
|
40
|
+
default: () => [],
|
41
41
|
},
|
42
42
|
field: {
|
43
43
|
type: String,
|
44
44
|
default: () => {
|
45
45
|
const _name = (l: any) => Array.from({ length: l }, () => 'abcdefghijklmnopqrstuvwxyz'[Math.floor(Math.random() * 26)]).join('');
|
46
46
|
return _name(8);
|
47
|
-
}
|
48
|
-
}
|
47
|
+
},
|
48
|
+
},
|
49
49
|
});
|
50
50
|
|
51
51
|
const mv: any = ref(props.modelValue);
|
@@ -106,14 +106,14 @@
|
|
106
106
|
() => {
|
107
107
|
mv.value = props.modelValue;
|
108
108
|
},
|
109
|
-
{ deep: true, immediate: true }
|
109
|
+
{ deep: true, immediate: true },
|
110
110
|
);
|
111
111
|
watch(
|
112
112
|
() => mv.value,
|
113
113
|
(v: any) => {
|
114
114
|
emits('update:modelValue', v);
|
115
115
|
},
|
116
|
-
{ deep: true, immediate: true }
|
116
|
+
{ deep: true, immediate: true },
|
117
117
|
);
|
118
118
|
|
119
119
|
const ready: any = ref(0);
|
@@ -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
|
// 更新
|
@@ -43,23 +43,23 @@
|
|
43
43
|
placeholder: { type: String, default: '' },
|
44
44
|
modelValue: {
|
45
45
|
type: Array as () => any[],
|
46
|
-
default: () => []
|
46
|
+
default: () => [],
|
47
47
|
},
|
48
48
|
options: {
|
49
49
|
type: Array as () => any[],
|
50
|
-
default: () => []
|
50
|
+
default: () => [],
|
51
51
|
},
|
52
52
|
rules: {
|
53
53
|
type: Array,
|
54
|
-
default: () => []
|
54
|
+
default: () => [],
|
55
55
|
},
|
56
56
|
field: {
|
57
57
|
type: String,
|
58
58
|
default: () => {
|
59
59
|
const _name = (l: any) => Array.from({ length: l }, () => 'abcdefghijklmnopqrstuvwxyz'[Math.floor(Math.random() * 26)]).join('');
|
60
60
|
return _name(8);
|
61
|
-
}
|
62
|
-
}
|
61
|
+
},
|
62
|
+
},
|
63
63
|
});
|
64
64
|
const mv: any = ref(props.modelValue);
|
65
65
|
const state: any = reactive({
|
@@ -75,7 +75,7 @@
|
|
75
75
|
}),
|
76
76
|
has: computed(() => {
|
77
77
|
return props.options?.some((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
|
78
|
-
})
|
78
|
+
}),
|
79
79
|
});
|
80
80
|
|
81
81
|
// 监听外部数据
|
@@ -86,7 +86,7 @@
|
|
86
86
|
const selectd: any = props.options?.filter((item: any) => v?.some((i: any) => `${i}` === `${item.value}`))?.map((item: any) => item.label) || [];
|
87
87
|
state.value = selectd.join(' Ι ') || '';
|
88
88
|
},
|
89
|
-
{ deep: true, immediate: true }
|
89
|
+
{ deep: true, immediate: true },
|
90
90
|
);
|
91
91
|
// 更新
|
92
92
|
const change = (item: any) => {
|
@@ -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
|
>
|
@@ -28,23 +28,23 @@
|
|
28
28
|
placeholder: { type: String, default: '' },
|
29
29
|
modelValue: {
|
30
30
|
type: Array as () => any[],
|
31
|
-
default: () => []
|
31
|
+
default: () => [],
|
32
32
|
},
|
33
33
|
options: {
|
34
34
|
type: Array as () => any[],
|
35
|
-
default: () => []
|
35
|
+
default: () => [],
|
36
36
|
},
|
37
37
|
rules: {
|
38
38
|
type: Array,
|
39
|
-
default: () => []
|
39
|
+
default: () => [],
|
40
40
|
},
|
41
41
|
field: {
|
42
42
|
type: String,
|
43
43
|
default: () => {
|
44
44
|
const _name = (l: any) => Array.from({ length: l }, () => 'abcdefghijklmnopqrstuvwxyz'[Math.floor(Math.random() * 26)]).join('');
|
45
45
|
return _name(8);
|
46
|
-
}
|
47
|
-
}
|
46
|
+
},
|
47
|
+
},
|
48
48
|
});
|
49
49
|
|
50
50
|
const mv: any = ref(props.modelValue);
|
@@ -105,14 +105,14 @@
|
|
105
105
|
() => {
|
106
106
|
mv.value = props.modelValue;
|
107
107
|
},
|
108
|
-
{ deep: true, immediate: true }
|
108
|
+
{ deep: true, immediate: true },
|
109
109
|
);
|
110
110
|
watch(
|
111
111
|
() => mv.value,
|
112
112
|
(v: any) => {
|
113
113
|
emits('update:modelValue', v);
|
114
114
|
},
|
115
|
-
{ deep: true, immediate: true }
|
115
|
+
{ deep: true, immediate: true },
|
116
116
|
);
|
117
117
|
|
118
118
|
const ready: any = ref(0);
|
@@ -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>
|
@@ -51,7 +51,7 @@
|
|
51
51
|
// 用户是否交互
|
52
52
|
interacted: {
|
53
53
|
type: Boolean,
|
54
|
-
default: false
|
54
|
+
default: false,
|
55
55
|
},
|
56
56
|
theme: { type: String, default: '@a' },
|
57
57
|
sz: { type: String, default: 'm' },
|
@@ -60,51 +60,51 @@
|
|
60
60
|
// 提示文案
|
61
61
|
tips: {
|
62
62
|
type: String,
|
63
|
-
default: ''
|
63
|
+
default: '',
|
64
64
|
},
|
65
65
|
placeholder: {
|
66
66
|
type: String,
|
67
|
-
default: ''
|
67
|
+
default: '',
|
68
68
|
},
|
69
69
|
options: {
|
70
70
|
type: Array as () => any[],
|
71
|
-
default: () => []
|
71
|
+
default: () => [],
|
72
72
|
},
|
73
73
|
ui: {
|
74
74
|
type: Object,
|
75
|
-
default: () => ({ sz: 'm' })
|
75
|
+
default: () => ({ sz: 'm' }),
|
76
76
|
},
|
77
77
|
modelValue: {
|
78
78
|
type: [String, Number],
|
79
|
-
default: ''
|
79
|
+
default: '',
|
80
80
|
},
|
81
81
|
// 校验规则
|
82
82
|
rules: {
|
83
83
|
type: Array,
|
84
|
-
default: () => []
|
84
|
+
default: () => [],
|
85
85
|
},
|
86
86
|
// 是否是示校验图标
|
87
87
|
verify: {
|
88
88
|
type: Boolean,
|
89
|
-
default: false
|
89
|
+
default: false,
|
90
90
|
},
|
91
91
|
tools: {
|
92
92
|
type: Boolean,
|
93
|
-
default: true
|
93
|
+
default: true,
|
94
94
|
},
|
95
95
|
spare: {
|
96
96
|
type: String,
|
97
|
-
default: '当前没有可选项'
|
97
|
+
default: '当前没有可选项',
|
98
98
|
},
|
99
99
|
// 分页
|
100
100
|
pageInfo: {
|
101
101
|
type: Object,
|
102
|
-
default: () => ({ total: 0, pages: 0, page: 0 })
|
102
|
+
default: () => ({ total: 0, pages: 0, page: 0 }),
|
103
103
|
},
|
104
104
|
filterable: {
|
105
105
|
type: Boolean,
|
106
|
-
default: false
|
107
|
-
}
|
106
|
+
default: false,
|
107
|
+
},
|
108
108
|
});
|
109
109
|
|
110
110
|
const emit = defineEmits(['update:modelValue', 'pageChange', 'searchChange']);
|
@@ -126,7 +126,7 @@
|
|
126
126
|
}
|
127
127
|
}
|
128
128
|
return _value;
|
129
|
-
})
|
129
|
+
}),
|
130
130
|
/* filter: computed(() => {
|
131
131
|
if (state.search) {
|
132
132
|
return props.options?.filter((item) => {
|
@@ -170,14 +170,14 @@
|
|
170
170
|
() => {
|
171
171
|
change({});
|
172
172
|
emit('searchChange', state.search);
|
173
|
-
}
|
173
|
+
},
|
174
174
|
);
|
175
175
|
|
176
176
|
defineExpose({
|
177
177
|
select,
|
178
178
|
remove,
|
179
179
|
change,
|
180
|
-
cancel
|
180
|
+
cancel,
|
181
181
|
});
|
182
182
|
</script>
|
183
183
|
<style lang="scss" scoped>
|