@neatui/vue 2.7.1 → 2.7.2
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/form/Upload.vue +23 -22
- package/src/components/loader/FormLoader/FormLoader@v2.vue +178 -180
- package/src/components/loader/TableLoader/index.ts +47 -0
- package/src/components/loader/TableLoader@v3/TableColView@v3.vue +155 -0
- package/src/components/loader/TableLoader@v3/TableLoader@v3.vue +636 -0
- package/src/components/loader/TableLoader@v3/index@v3.ts +41 -0
- package/src/components/loader/index.ts +2 -1
- package/src/components/tools/Pagination@a.vue +16 -17
- package/src/components/tools/Pagination@b.vue +16 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ui-flex="row lm :wrap" class="neatui-upload mb-sm-sub mr-sm-sub" v-bind="{ ...attrs }">
|
|
3
|
-
<div v-for="(file, idx) in state.files" :key="idx" ui-flex="col cm" class="flex-fixed bg-fore n-sl w-ms h-ms b-solid bk-case b-xs r-sm pr">
|
|
3
|
+
<div v-for="(file, idx) in state.files" :key="idx" ui-flex="col cm" class="flex-fixed bg-fore n-sl w-ms h-ms b-solid bk-case b-xs r-sm pr" v-bind="itemAttrs">
|
|
4
4
|
<!-- 删除按钮 -->
|
|
5
5
|
<div class="pa ot-ss or-ss bg-fore co-risk lh-xs r-xl parent-hover:show" @click="remove(idx)">
|
|
6
6
|
<svg class="block" viewBox="0 0 1024 1024" style="width: 1em; height: 1em">
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
</svg>
|
|
148
148
|
</template>
|
|
149
149
|
|
|
150
|
-
<!--
|
|
150
|
+
<!-- 上传状态 -->
|
|
151
151
|
<div v-if="file.status === 'uploading'" class="upload-status">
|
|
152
152
|
<div class="loading-spinner"></div>
|
|
153
153
|
<span class="status-text">上传中...</span>
|
|
@@ -155,14 +155,11 @@
|
|
|
155
155
|
<div v-else-if="file.status === 'error'" class="upload-status error">
|
|
156
156
|
<span class="status-text">上传失败</span>
|
|
157
157
|
</div>
|
|
158
|
-
|
|
159
|
-
<!-- 文件名 -->
|
|
160
|
-
<!-- <p ui-omit="1" class="fs-ss ac">{{ file.name }}</p> -->
|
|
161
158
|
</div>
|
|
162
159
|
|
|
163
160
|
<!-- 上传按钮 -->
|
|
164
161
|
<div v-if="showUploadButton">
|
|
165
|
-
<slot>
|
|
162
|
+
<slot name="btn">
|
|
166
163
|
<label ui-flex="row cm" ui-form="@a type:upload tips:hover" :class="`upload w-ms h-ms n-sl bg-fore b-solid bk-case b-xs r-sm ${uploadClass}`" :style="uploadStyle">
|
|
167
164
|
<div v-if="tips" ui-form-tips>
|
|
168
165
|
{{ tips }}
|
|
@@ -189,6 +186,7 @@
|
|
|
189
186
|
modelValue?: string | any[];
|
|
190
187
|
max?: number;
|
|
191
188
|
attrs?: object;
|
|
189
|
+
itemAttrs?: object;
|
|
192
190
|
uploadClass?: string;
|
|
193
191
|
uploadStyle?: string;
|
|
194
192
|
tips?: string;
|
|
@@ -196,6 +194,7 @@
|
|
|
196
194
|
upload?: (formData: FormData) => Promise<any>;
|
|
197
195
|
maxSize?: number;
|
|
198
196
|
compress?: boolean;
|
|
197
|
+
disabled?: boolean;
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -203,12 +202,14 @@
|
|
|
203
202
|
uploadClass: '',
|
|
204
203
|
uploadStyle: '',
|
|
205
204
|
attrs: () => ({}),
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
205
|
+
itemAttrs: () => ({}),
|
|
206
|
+
tips: '',
|
|
207
|
+
accept: '*',
|
|
208
|
+
upload: async () => null,
|
|
209
|
+
maxSize: 10,
|
|
210
|
+
compress: true,
|
|
211
|
+
max: 0,
|
|
212
|
+
disabled: false,
|
|
212
213
|
});
|
|
213
214
|
|
|
214
215
|
interface UploadFile {
|
|
@@ -226,7 +227,7 @@
|
|
|
226
227
|
isInternalUpdate: boolean; // 标记是否为内部更新
|
|
227
228
|
}>({
|
|
228
229
|
files: [],
|
|
229
|
-
isInternalUpdate: false
|
|
230
|
+
isInternalUpdate: false,
|
|
230
231
|
});
|
|
231
232
|
|
|
232
233
|
const emit = defineEmits(['update:modelValue', 'change', 'error']);
|
|
@@ -314,7 +315,7 @@
|
|
|
314
315
|
success: (result) => {
|
|
315
316
|
resolve(new File([result], file.name, { type: result.type }));
|
|
316
317
|
},
|
|
317
|
-
error: reject
|
|
318
|
+
error: reject,
|
|
318
319
|
});
|
|
319
320
|
});
|
|
320
321
|
};
|
|
@@ -395,7 +396,7 @@
|
|
|
395
396
|
type: getFileType(file),
|
|
396
397
|
path: previewUrl,
|
|
397
398
|
status: 'uploading',
|
|
398
|
-
size: file.size
|
|
399
|
+
size: file.size,
|
|
399
400
|
};
|
|
400
401
|
state.files.push(uploadFile);
|
|
401
402
|
validFiles.push({ file, uploadFile });
|
|
@@ -475,7 +476,7 @@
|
|
|
475
476
|
type: 'image',
|
|
476
477
|
path: item,
|
|
477
478
|
status: 'success' as const,
|
|
478
|
-
result: item
|
|
479
|
+
result: item,
|
|
479
480
|
};
|
|
480
481
|
} else {
|
|
481
482
|
// 如果是对象
|
|
@@ -484,7 +485,7 @@
|
|
|
484
485
|
type: item.type || 'file',
|
|
485
486
|
path: item.url || item.path || '',
|
|
486
487
|
status: 'success' as const,
|
|
487
|
-
result: item
|
|
488
|
+
result: item,
|
|
488
489
|
};
|
|
489
490
|
}
|
|
490
491
|
});
|
|
@@ -495,8 +496,8 @@
|
|
|
495
496
|
type: 'image',
|
|
496
497
|
path: newValue,
|
|
497
498
|
status: 'success',
|
|
498
|
-
result: newValue
|
|
499
|
-
}
|
|
499
|
+
result: newValue,
|
|
500
|
+
},
|
|
500
501
|
];
|
|
501
502
|
} else if (newValue && typeof newValue === 'object') {
|
|
502
503
|
const objValue = newValue as any;
|
|
@@ -506,14 +507,14 @@
|
|
|
506
507
|
type: objValue.type || 'file',
|
|
507
508
|
path: objValue.url || objValue.path || '',
|
|
508
509
|
status: 'success',
|
|
509
|
-
result: newValue
|
|
510
|
-
}
|
|
510
|
+
result: newValue,
|
|
511
|
+
},
|
|
511
512
|
];
|
|
512
513
|
} else {
|
|
513
514
|
state.files = [];
|
|
514
515
|
}
|
|
515
516
|
},
|
|
516
|
-
{ immediate: true, deep: true }
|
|
517
|
+
{ immediate: true, deep: true },
|
|
517
518
|
);
|
|
518
519
|
|
|
519
520
|
// 组件销毁时清理资源
|
|
@@ -1,186 +1,184 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<div
|
|
175
|
-
<
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<
|
|
179
|
-
<slot name="submit"></slot>
|
|
180
|
-
</div>
|
|
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="full-w" 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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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="full-w"
|
|
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
|
+
<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] || {}) }" />
|
|
157
|
+
<Cascader
|
|
158
|
+
v-else-if="col.model[0] === 'Cascader'"
|
|
159
|
+
v-model="col._data[col.field]"
|
|
160
|
+
:interacted="interacted"
|
|
161
|
+
:options="col.enums"
|
|
162
|
+
:rules="col.rules"
|
|
163
|
+
class="full-w"
|
|
164
|
+
v-bind="{ ...(col.model[1] || {}) }"
|
|
165
|
+
/>
|
|
166
|
+
<template v-else>
|
|
167
|
+
<slot v-if="col.slot" :name="col.slot" :col="col"></slot>
|
|
168
|
+
<slot v-else-if="col.model[0]" :name="col.model[0]" :col="col"></slot>
|
|
169
|
+
<slot v-else :name="col.field" :col="col"></slot>
|
|
170
|
+
</template>
|
|
171
|
+
</div>
|
|
172
|
+
</template>
|
|
173
|
+
<div :ui-flex="`${vertical ? 'col xm' : 'row xt'}`">
|
|
174
|
+
<div v-if="vertical">
|
|
175
|
+
<slot name="submit"></slot>
|
|
176
|
+
</div>
|
|
177
|
+
<div v-else :style="`padding-left:${state._lw + 'em'};`">
|
|
178
|
+
<slot name="submit"></slot>
|
|
181
179
|
</div>
|
|
182
180
|
</div>
|
|
183
|
-
</
|
|
181
|
+
</div>
|
|
184
182
|
</template>
|
|
185
183
|
<script lang="ts" setup>
|
|
186
184
|
import { watch, reactive, onBeforeUnmount, nextTick } from 'vue';
|
|
@@ -1,2 +1,49 @@
|
|
|
1
|
+
import { isFunction } from '@fekit/utils';
|
|
1
2
|
import TableLoader from './TableLoader.vue';
|
|
3
|
+
|
|
4
|
+
// 类型定义
|
|
5
|
+
interface ListItem {
|
|
6
|
+
__selected?: boolean;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type KeyExtractor<T = ListItem> = string | ((item: T) => any);
|
|
11
|
+
|
|
2
12
|
export default TableLoader;
|
|
13
|
+
|
|
14
|
+
// 是否有选中记录
|
|
15
|
+
export const hasSelected = (lists: ListItem[] = []): boolean => {
|
|
16
|
+
return lists.some((item) => item.__selected === true);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// 获取选中记录的数量
|
|
20
|
+
export const getSelectedCount = (lists: ListItem[] = []): number => {
|
|
21
|
+
return lists.filter((item) => item.__selected === true).length;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// 获取选中的记录
|
|
25
|
+
export const getSelected = <T extends Record<string, any> = ListItem>(lists: T[] = [], key: KeyExtractor<T> = ''): any[] => {
|
|
26
|
+
return (
|
|
27
|
+
lists
|
|
28
|
+
?.filter((item: T) => {
|
|
29
|
+
return item.__selected === true;
|
|
30
|
+
})
|
|
31
|
+
?.map((item: T) => {
|
|
32
|
+
return isFunction(key) ? (key as (item: T) => any)(item) : key ? item[key as string] : item;
|
|
33
|
+
}) || []
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// 全选计算属性
|
|
38
|
+
export function allSelected(lists: ListItem[] = []) {
|
|
39
|
+
return {
|
|
40
|
+
get(): boolean {
|
|
41
|
+
return lists.length > 0 && lists.every((item) => item.__selected === true);
|
|
42
|
+
},
|
|
43
|
+
set(value: boolean): void {
|
|
44
|
+
lists.forEach((item) => {
|
|
45
|
+
item.__selected = value;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|