@neatui/vue 2.17.3 → 3.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 (29) hide show
  1. package/.prettierrc +12 -0
  2. package/README.md +82 -0
  3. package/package.json +7 -4
  4. package/src/components/basic/IFollowView.vue +47 -34
  5. package/src/components/basic/IPickerView.vue +16 -8
  6. package/src/components/basic/IRouterView.vue +133 -74
  7. package/src/components/basic/IScrollView.vue +110 -93
  8. package/src/components/basic/LayerView/Layer.vue +33 -24
  9. package/src/components/basic/LayerView/index.ts +3 -1
  10. package/src/components/form/DateView@v3.vue +2 -1
  11. package/src/components/form/Input@v3.vue +9 -6
  12. package/src/components/form/{Textarea.vue → TextArea.vue} +3 -3
  13. package/src/components/loader/FormLoader/FormLoader.vue +29 -4
  14. package/src/components/loader/LayerLoader/LayerLoader.vue +2 -1
  15. package/src/components/loader/LimitLoader/LimitLoader@v3.vue +3 -3
  16. package/src/components/loader/TableLoader/TableLoader.vue +3 -3
  17. package/src/components/loader/index.ts +1 -1
  18. package/src/components/tools/FormDraftsView.vue +15 -11
  19. package/src/components/tools/FormVerifyView.vue +4 -3
  20. package/src/components/tools/MoreTools.vue +4 -3
  21. package/src/components/tools/Pagination@a.vue +74 -38
  22. package/src/components/tools/Pagination@b.vue +2 -1
  23. package/src/store/frame.ts +18 -10
  24. package/src/utils/theme.ts +3 -0
  25. package/src/components/basic/follow.ts +0 -133
  26. package/src/components/loader/FormLoader/FormLoader@v2.vue +0 -422
  27. package/src/components/loader/FormLoader/NodeLoader.vue +0 -85
  28. package/src/components/loader/FormLoader@v1/FormLoader.vue +0 -506
  29. package/src/components/loader/FormLoader@v1/FormRender.vue +0 -302
@@ -1,422 +0,0 @@
1
- <template>
2
- <div :ui-row="rows" class="n-sl-sub">
3
- <template v-for="(col, idx) in state.form" :key="idx">
4
- <div v-if="!col.clear" :id="col._fid" :ui-col="col.media" :ui-flex="`${vertical ? 'col xm' : 'row lt'}`">
5
- <template v-if="col.label">
6
- <h6 v-if="vertical" :style="`${col.rules?.some((validator: any) => validator.required) ? 'text-indent: -1em' : ''}`" class="o-ls">
7
- <template v-if="col.label == '*'"></template>
8
- <template v-else>
9
- <b v-if="col.rules?.some((validator: any) => validator.required)" class="co-risk pr" style="left: 0.1em">﹡</b>
10
- <span>{{ col.label ? col.label + ':' : '' }}</span>
11
- </template>
12
- </h6>
13
- <p v-else :class="`${clh({ ...(col.model[1] || {}) })}`" :style="`width:${state._lw + 'em'}; max-width:50%;`" class="ar nr-sm flex-fixed o-ls">
14
- <template v-if="col.label == '*'"></template>
15
- <template v-else>
16
- <b v-if="col.rules?.some((validator: any) => validator.required)" class="co-risk">﹡</b>
17
- <span>{{ col.label ? col.label + ':' : '' }}</span>
18
- </template>
19
- </p>
20
- </template>
21
- <Input v-if="col.model[0] === 'Input'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" class="w-full" v-bind="{ ...(col.model[1] || {}) }" />
22
- <Select
23
- v-else-if="col.model[0] === 'Select'"
24
- v-model="col._data[col.field]"
25
- :interacted="interacted"
26
- :options="col.enums"
27
- :rules="col?.rules"
28
- class="w-full"
29
- v-bind="{ ...(col.model[1] || {}) }"
30
- ></Select>
31
- <SelectList
32
- v-else-if="col.model[0] === 'SelectList'"
33
- v-model="col._data[col.field]"
34
- :interacted="interacted"
35
- :options="col.enums"
36
- :rules="col?.rules"
37
- class="w-full"
38
- v-bind="{ ...(col.model[1] || {}) }"
39
- />
40
- <SelectTags
41
- v-else-if="col.model[0] === 'SelectTags'"
42
- v-model="col._data[col.field]"
43
- :interacted="interacted"
44
- :options="col.enums"
45
- :rules="col?.rules"
46
- class="w-full"
47
- v-bind="{ ...(col.model[1] || {}) }"
48
- />
49
- <SelectPicker
50
- v-else-if="col.model[0] === 'SelectPicker'"
51
- v-model="col._data[col.field]"
52
- :interacted="interacted"
53
- :options="col.enums"
54
- :rules="col?.rules"
55
- class="w-full"
56
- v-bind="{ ...(col.model[1] || {}) }"
57
- />
58
- <SearchSelect
59
- v-else-if="col.model[0] === 'SearchSelect'"
60
- v-model="col._data[col.field]"
61
- :interacted="interacted"
62
- :options="col.enums"
63
- :rules="col.rules"
64
- class="w-full"
65
- v-bind="{ ...(col.model[1] || {}) }"
66
- />
67
- <MoreSelect
68
- v-else-if="col.model[0] === 'MoreSelect'"
69
- v-model="col._data[col.field]"
70
- :interacted="interacted"
71
- :options="col.enums"
72
- :rules="col.rules"
73
- class="w-full"
74
- v-bind="{ ...(col.model[1] || {}) }"
75
- />
76
- <MoreSelectList
77
- v-else-if="col.model[0] === 'MoreSelectList'"
78
- v-model="col._data[col.field]"
79
- :interacted="interacted"
80
- :options="col.enums"
81
- :rules="col.rules"
82
- class="w-full"
83
- v-bind="{ ...(col.model[1] || {}) }"
84
- />
85
- <MoreSelectTags
86
- v-else-if="col.model[0] === 'MoreSelectTags'"
87
- v-model="col._data[col.field]"
88
- :interacted="interacted"
89
- :options="col.enums"
90
- :rules="col.rules"
91
- class="w-full"
92
- v-bind="{ ...(col.model[1] || {}) }"
93
- />
94
- <MoreSelectPicker
95
- v-else-if="col.model[0] === 'MoreSelectPicker'"
96
- v-model="col._data[col.field]"
97
- :interacted="interacted"
98
- :options="col.enums"
99
- :rules="col.rules"
100
- class="w-full"
101
- v-bind="{ ...(col.model[1] || {}) }"
102
- />
103
- <SearchMoreSelect
104
- v-else-if="col.model[0] === 'SearchMoreSelect'"
105
- v-model="col._data[col.field]"
106
- :interacted="interacted"
107
- :options="col.enums"
108
- :rules="col.rules"
109
- class="w-full"
110
- v-bind="{ ...(col.model[1] || {}) }"
111
- />
112
- <PageSelect
113
- v-else-if="col.model[0] === 'PageSelect'"
114
- v-model="col._data[col.field]"
115
- :interacted="interacted"
116
- :options="col.enums"
117
- :rules="col.rules"
118
- class="w-full"
119
- v-bind="{ ...(col.model[1] || {}) }"
120
- />
121
- <SelectTree
122
- v-else-if="col.model[0] === 'SelectTree'"
123
- v-model="col._data[col.field]"
124
- :interacted="interacted"
125
- :options="col.enums"
126
- :rules="col.rules"
127
- class="w-full"
128
- v-bind="{ ...(col.model[1] || {}) }"
129
- />
130
- <DatePicker
131
- v-else-if="col.model[0] === 'DatePicker'"
132
- v-model="col._data[col.field]"
133
- :interacted="interacted"
134
- :rules="col.rules"
135
- class="w-full"
136
- v-bind="{ ...(col.model[1] || {}) }"
137
- />
138
- <DateRangePicker
139
- v-else-if="col.model[0] === 'DateRangePicker'"
140
- v-model="col._data[col.field]"
141
- :interacted="interacted"
142
- :rules="col.rules"
143
- class="w-full"
144
- v-bind="{ ...(col.model[1] || {}) }"
145
- />
146
- <ImgUpload v-else-if="col.model[0] === 'ImgUpload'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" v-bind="{ ...(col.model[1] || {}) }" />
147
- <Upload v-else-if="col.model[0] === 'Upload'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" v-bind="{ ...(col.model[1] || {}) }" />
148
- <Textarea
149
- v-else-if="col.model[0] === 'Textarea'"
150
- v-model="col._data[col.field]"
151
- :interacted="interacted"
152
- :rules="col.rules"
153
- v-bind="{ ...(col.model[1] || {}) }"
154
- ></Textarea>
155
- <Switch v-else-if="col.model[0] === 'Switch'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" v-bind="{ ...(col.model[1] || {}) }" />
156
- <Checkbox v-else-if="col.model[0] === 'Checkbox'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" v-bind="{ ...(col.model[1] || {}) }" />
157
- <Tree v-else-if="col.model[0] === 'Tree'" v-model="col._data[col.field]" :interacted="interacted" :rules="col.rules" class="mt-sm" v-bind="{ ...(col.model[1] || {}) }" />
158
- <Cascader
159
- v-else-if="col.model[0] === 'Cascader'"
160
- v-model="col._data[col.field]"
161
- :interacted="interacted"
162
- :options="col.enums"
163
- :rules="col.rules"
164
- class="w-full"
165
- v-bind="{ ...(col.model[1] || {}) }"
166
- />
167
- <template v-else>
168
- <slot v-if="col.slot" :name="col.slot" :col="col"></slot>
169
- <slot v-else-if="col.model[0]" :name="col.model[0]" :col="col"></slot>
170
- <slot v-else :name="col.field" :col="col"></slot>
171
- </template>
172
- </div>
173
- </template>
174
- <div :ui-flex="`${vertical ? 'col xm' : 'row xt'}`">
175
- <div v-if="vertical">
176
- <slot name="submit"></slot>
177
- </div>
178
- <div v-else :style="`padding-left:${state._lw + 'em'};`">
179
- <slot name="submit"></slot>
180
- </div>
181
- </div>
182
- </div>
183
- </template>
184
- <script lang="ts" setup>
185
- import { watch, reactive, onBeforeUnmount, nextTick } from 'vue';
186
- import { useRoute, useRouter } from 'vue-router';
187
- import { isString, isObject, isFunction, deepcopy, isArray } from '@fekit/utils';
188
- import {
189
- Input,
190
- Switch,
191
- Checkbox,
192
- Textarea,
193
- Select,
194
- SelectList,
195
- SelectTags,
196
- SelectPicker,
197
- SearchSelect,
198
- PageSelect,
199
- SelectTree,
200
- MoreSelect,
201
- MoreSelectList,
202
- MoreSelectTags,
203
- MoreSelectPicker,
204
- DatePicker,
205
- DateRangePicker,
206
- SearchMoreSelect,
207
- ImgUpload,
208
- Upload,
209
- Cascader,
210
- } from '../../form';
211
- import { Tree } from '../../display';
212
-
213
- const route = useRoute();
214
- const router = useRouter();
215
-
216
- // 计算Label行高
217
- const clh = ({ sz = '' }: any = {}) => {
218
- const lhs: any = { xs: 'lh-sm', s: 'lh-mm', m: 'lh-ls', l: 'lh-ll', xl: 'lh-xl' };
219
- return lhs[sz] || 'lh-ls';
220
- };
221
-
222
- // 计算Label宽度
223
- function clw(label: any = '') {
224
- let emWidth = 0;
225
- if (isString(label)) {
226
- for (let i = 0; i < label.length; i++) {
227
- const char = label[i];
228
- if (/^[\u4e00-\u9fa5]+$/.test(char)) {
229
- emWidth += 1;
230
- } else {
231
- emWidth += 0.5;
232
- }
233
- }
234
- }
235
- return emWidth;
236
- }
237
-
238
- // 入参
239
- const props: any = defineProps({
240
- // 用户是否交互
241
- interacted: {
242
- type: Boolean,
243
- default: false,
244
- },
245
- // JSON规则
246
- form: {
247
- type: Object,
248
- default: () => ({}),
249
- },
250
- // 表单数据
251
- data: {
252
- type: Object as any,
253
- default: () => ({}),
254
- },
255
- // 栅格系统
256
- rows: {
257
- type: String,
258
- default: 'mob-24 pad-12 dpc-8',
259
- },
260
- // 如果表单是数组的话这里传入下标
261
- idx: {
262
- type: [String, Number],
263
- default: '',
264
- },
265
- // 是否垂直排列
266
- vertical: {
267
- type: Boolean,
268
- default: false,
269
- },
270
- });
271
-
272
- // 数据
273
- const state: any = reactive({
274
- form: [],
275
- _lw: 6,
276
- });
277
-
278
- // 监听结构
279
- const unwatchs: any = [];
280
- watch(
281
- [() => props.form, () => props.data, () => props.idx],
282
- ([form = []]) => {
283
- const wkeys: any = {};
284
- const onces: any = [];
285
- state.form = deepcopy(form)?.map((item: any = {}, idx: number) => {
286
- // 计算Label宽度
287
- const _w = clw(item.label) + 2;
288
- if (_w > state._lw) {
289
- state._lw = _w;
290
- }
291
-
292
- if (isObject(item)) {
293
- for (const key in item) {
294
- let val = item[key] || {};
295
- // 处理函数
296
- if (isFunction(val)) {
297
- val = val(deepcopy(props.data), props.form, route, router);
298
- if (isObject(val)) {
299
- if (!isFunction(val.setup)) {
300
- val.setup = item[key];
301
- }
302
- if (!isArray(val.watch)) {
303
- val.watch = deepcopy(form).map(({ field = '' }: any = {}) => field);
304
- }
305
- } else {
306
- val = { value: val, setup: item[key], watch: deepcopy(form).map(({ field = '' }: any = {}) => field) };
307
- }
308
- }
309
- // 对象处理
310
- if (isObject(val)) {
311
- const { value = null, setup = () => {}, watch: _watch = [] } = val || {};
312
- // 监听字段为空
313
- if (_watch.length) {
314
- _watch?.forEach((k: any) => {
315
- if (wkeys[k]) {
316
- wkeys[k].push({ idx, key, value, setup });
317
- } else {
318
- wkeys[k] = [{ idx, key, value, setup }];
319
- }
320
- });
321
- } else {
322
- onces.push({ idx, key, value, setup });
323
- }
324
- item[key] = value;
325
- } else {
326
- item[key] = val;
327
- }
328
- }
329
- }
330
-
331
- // 模型处理
332
- if (item.model) {
333
- if (isString(item.model)) {
334
- item.model = [item.model, { verify: false }];
335
- }
336
- } else {
337
- item.model = ['', { verify: false }];
338
- }
339
- if (item.model[1] && !Object.prototype.hasOwnProperty.call(item.model[1], 'verify')) {
340
- item.model[1].verify = false;
341
- }
342
-
343
- // 添加ID
344
- item._fid = `form-${props.idx !== '' ? props.idx + '-' : ''}field-${item.field}`;
345
-
346
- // 数据路径处理
347
- item._data = props.data;
348
- (item.paths?.split('.') || [])?.forEach((i: any) => {
349
- if (item._data[i]) {
350
- item._data = item._data[i];
351
- }
352
- });
353
- return item;
354
- });
355
- const runsetup = (item: any = {}) => {
356
- const { idx = null, key = null, value = null, setup = null }: any = item || {};
357
- if (state.form[idx] && isFunction(setup)) {
358
- const v = setup(deepcopy(props.data), state.form[idx], route, router);
359
- nextTick(() => {
360
- if (v instanceof Promise) {
361
- state.form[idx][key] = value;
362
- v.then((res: any) => {
363
- state.form[idx][key] = res;
364
- });
365
- } else {
366
- state.form[idx][key] = v;
367
- }
368
- });
369
- }
370
- };
371
- // 执行一次
372
- onces?.forEach((item: any = {}) => {
373
- runsetup(item);
374
- });
375
- // 监听列表
376
- for (const key in wkeys) {
377
- unwatchs.push(
378
- watch(
379
- () => props.data[key],
380
- () => {
381
- wkeys[key]?.forEach((item: any = {}) => {
382
- runsetup(item);
383
- });
384
- },
385
- {
386
- deep: true,
387
- immediate: true,
388
- },
389
- ),
390
- );
391
- }
392
- },
393
- { deep: true, immediate: true },
394
- );
395
-
396
- // 处理
397
- watch(
398
- [() => state.form, () => props.data],
399
- () => {
400
- state.form.forEach((item: any = {}) => {
401
- const { clear = false, field = '', paths = '' }: any = item;
402
- if (clear) {
403
- // 数据路径处理
404
- let _data = props.data;
405
- (paths?.split('.') || [])?.forEach((i: any) => {
406
- if (_data[i]) {
407
- _data = item._data[i];
408
- }
409
- });
410
- _data[field] = isArray(_data[field]) ? [] : '';
411
- }
412
- });
413
- },
414
- { deep: true },
415
- );
416
-
417
- onBeforeUnmount(() => {
418
- unwatchs?.forEach((unwatch: any) => {
419
- unwatch();
420
- });
421
- });
422
- </script>
@@ -1,85 +0,0 @@
1
- <template>
2
- <template v-for="(item, index) in $nodes" :key="item.paths">
3
- <div class="fekit-node-loader" :data-level="level" :data-index="index" :data-paths="item.paths" v-bind="item.attrs" v-on="item.$events" v-html="item.value"></div>
4
- <NodeLoader v-if="item.child" :nodes="item.child" :level="$level" :index="index" :paths="item.paths" />
5
- </template>
6
- </template>
7
- <script setup lang="ts">
8
- import { computed } from 'vue';
9
- import NodeLoader from './NodeLoader.vue';
10
-
11
- interface NodeProps {
12
- label?: string | ((data: any) => string);
13
- field?: string | ((data: any) => string);
14
- model?: string | ((data: any) => string);
15
- attrs?: Record<string, any> | ((data: any) => Record<string, any>);
16
- clear?: boolean | ((data: any) => boolean);
17
- media?: string | ((data: any) => string);
18
- value?: any | ((data: any) => any);
19
- event?: Record<string, any> | ((data: any) => Record<string, any>);
20
- child?: NodeProps[];
21
- }
22
-
23
- interface Props {
24
- nodes: NodeProps[];
25
- level?: number;
26
- index?: number;
27
- paths?: string;
28
- }
29
- const props = withDefaults(defineProps<Props>(), {
30
- nodes: () => [],
31
- level: 0,
32
- index: 0,
33
- paths: '',
34
- });
35
-
36
- const $nodes = computed(() => {
37
- return props.nodes.map((item, index) => {
38
- const paths = props.paths ? `${props.paths}-${index}` : `${index}`;
39
- const context = { node: item, level: props.level, index, paths } as const;
40
-
41
- let attrs: any = item.attrs;
42
- if (typeof attrs === 'function') {
43
- try {
44
- attrs = attrs(context);
45
- } catch {
46
- /* noop */
47
- }
48
- }
49
-
50
- let value: any = (item as any).value;
51
- if (typeof value === 'function') {
52
- try {
53
- value = value(context);
54
- } catch {
55
- /* noop */
56
- }
57
- }
58
-
59
- let ev: any = (item as any).event;
60
- if (typeof ev === 'function') {
61
- try {
62
- ev = ev(context);
63
- } catch {
64
- ev = undefined;
65
- }
66
- }
67
-
68
- const $events: Record<string, any> = {};
69
- if (ev && typeof ev === 'object') {
70
- for (const key in ev) {
71
- const fn = ev[key];
72
- if (typeof fn === 'function') {
73
- $events[key] = (...args: any[]) => fn(context, ...args);
74
- }
75
- }
76
- }
77
-
78
- return { ...item, index, paths, attrs, value, $events } as any;
79
- });
80
- });
81
-
82
- const $level = computed(() => {
83
- return props.level + 1;
84
- });
85
- </script>