@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.
Files changed (84) hide show
  1. package/BUILD.md +128 -0
  2. package/README.md +98 -1
  3. package/SSR_COMPATIBILITY.md +201 -0
  4. package/USAGE.md +260 -0
  5. package/nuxt.config.example.ts +37 -0
  6. package/package.json +29 -11
  7. package/src/components/basic/IDraggable.vue +87 -65
  8. package/src/components/basic/IFollowView.vue +32 -23
  9. package/src/components/basic/IRouterView.vue +38 -23
  10. package/src/components/basic/IScrollView.vue +11 -7
  11. package/src/components/basic/Icon.vue +17 -17
  12. package/src/components/basic/LayerView/Layer.vue +33 -106
  13. package/src/components/basic/follow.ts +133 -0
  14. package/src/components/display/Calendar.vue +14 -14
  15. package/src/components/display/CalendarReg.vue +14 -14
  16. package/src/components/display/Image.vue +8 -8
  17. package/src/components/display/PhotoEditor.vue +36 -36
  18. package/src/components/display/PhotoViewer.vue +8 -8
  19. package/src/components/display/Tree.vue +6 -6
  20. package/src/components/display/TreeView.vue +4 -4
  21. package/src/components/display/index.ts +2 -2
  22. package/src/components/form/Cascader.vue +19 -19
  23. package/src/components/form/Checkbox.vue +64 -0
  24. package/src/components/form/DatePicker.vue +6 -7
  25. package/src/components/form/DateRangePicker@v3.vue +4 -4
  26. package/src/components/form/DateRangeView@v3.vue +18 -19
  27. package/src/components/form/DateView.vue +14 -14
  28. package/src/components/form/DateView@v2.vue +14 -14
  29. package/src/components/form/DateView@v3.vue +331 -318
  30. package/src/components/form/ImgUpload.vue +7 -7
  31. package/src/components/form/Input@v3.vue +11 -11
  32. package/src/components/form/MoreSelect@v3.vue +87 -17
  33. package/src/components/form/MoreSelectList.vue +8 -8
  34. package/src/components/form/MoreSelectPanel@v3.vue +3 -3
  35. package/src/components/form/MoreSelectPicker.vue +7 -7
  36. package/src/components/form/MoreSelectTags.vue +8 -8
  37. package/src/components/form/PageMoreSelect.vue +14 -14
  38. package/src/components/form/PageSelect.vue +16 -16
  39. package/src/components/form/SearchMoreSelect.vue +12 -12
  40. package/src/components/form/SearchSelect@v3.vue +3 -3
  41. package/src/components/form/Select@v3.vue +229 -23
  42. package/src/components/form/SelectList.vue +8 -8
  43. package/src/components/form/SelectPicker.vue +6 -6
  44. package/src/components/form/SelectTags.vue +7 -7
  45. package/src/components/form/SelectTree/SelectTree@v1.vue +5 -5
  46. package/src/components/form/Switch.vue +38 -103
  47. package/src/components/form/TextArea.vue +18 -18
  48. package/src/components/form/Textarea@v2.vue +275 -0
  49. package/src/components/form/TimeView.vue +14 -14
  50. package/src/components/form/Upload.vue +806 -297
  51. package/src/components/form/date.ts +321 -0
  52. package/src/components/form/index.ts +7 -5
  53. package/src/components/form/number.ts +3 -0
  54. package/src/components/form/type.ts +224 -0
  55. package/src/components/icon/OrderIcon.vue +113 -0
  56. package/src/components/loader/FormLoader/FormLoader@v2.vue +193 -195
  57. package/src/components/loader/FormLoader/FormLoader@v3.vue.backup +372 -291
  58. package/src/components/loader/FormLoader/FormRender@v3.vue.backup +4 -0
  59. package/src/components/loader/FormLoader/NodeLoader.vue +85 -0
  60. package/src/components/loader/FormLoader@v1/FormLoader.vue +1 -1
  61. package/src/components/loader/FormLoader@v1/FormRender.vue +49 -24
  62. package/src/components/loader/LayerLoader/LayerLoader.vue +318 -0
  63. package/src/components/loader/LayerLoader/index.ts +2 -0
  64. package/src/components/loader/LayerLoader/style.scss +77 -0
  65. package/src/components/loader/LimitLoader/LimitLoader@v3.vue +39 -28
  66. package/src/components/loader/MoveLoader/MoveLoader.vue +628 -0
  67. package/src/components/loader/MoveLoader/index.ts +2 -0
  68. package/src/components/loader/MoveLoader/style.scss +77 -0
  69. package/src/components/loader/TableLoader/TableLoader.vue +227 -195
  70. package/src/components/loader/TableLoader/TableRender.vue +141 -0
  71. package/src/components/loader/TableLoader/index.ts +47 -0
  72. package/src/components/loader/index.ts +3 -2
  73. package/src/components/tools/Pagination@a.vue +17 -18
  74. package/src/components/tools/Pagination@b.vue +16 -16
  75. package/src/index.ts +2 -1
  76. package/src/module.ts +169 -0
  77. package/src/runtime/types.d.ts +36 -0
  78. package/src/store/{myui.ts → frame.ts} +4 -4
  79. package/src/utils/theme.ts +14 -0
  80. package/tsconfig.json +1 -1
  81. package/src/components/loader/FormLoader/index.ts +0 -2
  82. package/src/components/loader/LimitLoader/LimitLoader.vue.backup +0 -131
  83. package/src/components/loader/LimitLoader/LimitLoader@v2.vue.backup +0 -174
  84. 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:${sz}`" :ui-form-open="state.show ? 'show' : ''">
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.selectd.label"
6
+ v-model="state.displayLabel"
7
7
  :interacted="interacted"
8
8
  >
9
- <template #suffix><i ui-form-select=""></i></template>
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="props.options?.length" ui-scroll=":y s" class="nx-sm lh-sl" style="min-width: 100%; max-height: 16em">
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.value === state.selectd?.value ? 'co-main' : ''">
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.value === state.selectd?.value ? 'co-main' : ''" @click="select(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.filter?.length || 0 }}个可选项</span>
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
- tools: true,
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: false,
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 = ({ value = '' }: any = {}) => {
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
- return props?.options?.find((option: any) => `${option.value}` === `${props.modelValue}`) || {};
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
- return props.options?.filter((item: any) => {
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
- change(item);
173
- ifollow.value.cancel();
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
  .. ..