Commit 815250ed341ccaec23e7ea34db6cc478a47ad065
1 parent
c8ef82b2
fix: update upload component
Showing
7 changed files
with
183 additions
and
34 deletions
src/components/Upload/src/FileList.less
0 → 100644
1 | +@import (reference) '../../../design/index.less'; | |
2 | + | |
3 | +.file-table { | |
4 | + width: 100%; | |
5 | + border-collapse: collapse; | |
6 | + // border: 1px solid @border-color-light; | |
7 | + | |
8 | + .center { | |
9 | + text-align: center; | |
10 | + } | |
11 | + | |
12 | + .left { | |
13 | + text-align: left; | |
14 | + } | |
15 | + | |
16 | + .right { | |
17 | + text-align: right; | |
18 | + } | |
19 | + | |
20 | + &-th, | |
21 | + &-td { | |
22 | + padding: 12px 8px; | |
23 | + } | |
24 | + | |
25 | + thead { | |
26 | + background-color: @background-color-dark; | |
27 | + } | |
28 | + | |
29 | + table, | |
30 | + td, | |
31 | + th { | |
32 | + border: 1px solid @border-color-light; | |
33 | + } | |
34 | +} | ... | ... |
src/components/Upload/src/FileList.tsx
0 → 100644
1 | +import { defineComponent } from 'vue'; | |
2 | +import { fileListProps } from './props'; | |
3 | +import { isFunction } from '/@/utils/is'; | |
4 | +import './FileList.less'; | |
5 | + | |
6 | +export default defineComponent({ | |
7 | + name: 'FileList', | |
8 | + props: fileListProps, | |
9 | + setup(props) { | |
10 | + return () => { | |
11 | + const { columns, actionColumn, dataSource } = props; | |
12 | + | |
13 | + return ( | |
14 | + <table class="file-table"> | |
15 | + <colgroup> | |
16 | + {[...columns, actionColumn].map((item) => { | |
17 | + const { width = 0 } = item; | |
18 | + return width ? ( | |
19 | + <col style={'width:' + width + 'px;min-width:' + width + 'px;'} /> | |
20 | + ) : ( | |
21 | + <col /> | |
22 | + ); | |
23 | + })} | |
24 | + </colgroup> | |
25 | + <thead> | |
26 | + <tr class="file-table-tr"> | |
27 | + {[...columns, actionColumn].map((item) => { | |
28 | + const { title = '', align = 'center' } = item; | |
29 | + return <th class={['file-table-th', align]}>{title}</th>; | |
30 | + })} | |
31 | + </tr> | |
32 | + </thead> | |
33 | + <tbody> | |
34 | + {dataSource.map((record = {}) => { | |
35 | + return ( | |
36 | + <tr class="file-table-tr"> | |
37 | + {[...columns, actionColumn].map((item) => { | |
38 | + const { dataIndex = '', customRender, align = 'center' } = item; | |
39 | + if (customRender && isFunction(customRender)) { | |
40 | + return ( | |
41 | + <td class={['file-table-td', align]}> | |
42 | + {customRender({ text: record[dataIndex], record })} | |
43 | + </td> | |
44 | + ); | |
45 | + } else { | |
46 | + return <td class={['file-table-td', align]}>{record[dataIndex]}</td>; | |
47 | + } | |
48 | + })} | |
49 | + </tr> | |
50 | + ); | |
51 | + })} | |
52 | + </tbody> | |
53 | + </table> | |
54 | + ); | |
55 | + }; | |
56 | + }, | |
57 | +}); | ... | ... |
src/components/Upload/src/UploadModal.vue
... | ... | @@ -23,24 +23,25 @@ |
23 | 23 | {{ getUploadBtnText }} |
24 | 24 | </a-button> |
25 | 25 | </template> |
26 | - | |
27 | - <BasicTable @register="registerTable" :dataSource="fileListRef"> | |
28 | - <template #toolbar> | |
29 | - <Upload :accept="getStringAccept" :multiple="multiple" :before-upload="beforeUpload"> | |
30 | - <a-button type="primary"> 选择文件 </a-button> | |
31 | - </Upload> | |
32 | - </template> | |
33 | - <template #tableTitle> | |
34 | - <Alert :message="getHelpText" type="info" banner></Alert> | |
35 | - </template> | |
36 | - </BasicTable> | |
26 | + <div class="upload-modal-toolbar"> | |
27 | + <Alert :message="getHelpText" type="info" banner class="upload-modal-toolbar__text"></Alert> | |
28 | + <Upload | |
29 | + :accept="getStringAccept" | |
30 | + :multiple="multiple" | |
31 | + :before-upload="beforeUpload" | |
32 | + class="upload-modal-toolbar__btn" | |
33 | + > | |
34 | + <a-button type="primary"> 选择文件 </a-button> | |
35 | + </Upload> | |
36 | + </div> | |
37 | + <FileList :dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn" /> | |
37 | 38 | </BasicModal> |
38 | 39 | </template> |
39 | 40 | <script lang="ts"> |
40 | 41 | import { defineComponent, reactive, ref, toRefs, unref, computed } from 'vue'; |
41 | 42 | import { Upload, Alert } from 'ant-design-vue'; |
42 | 43 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
43 | - import { BasicTable, useTable } from '/@/components/Table'; | |
44 | + // import { BasicTable, useTable } from '/@/components/Table'; | |
44 | 45 | // hooks |
45 | 46 | import { useUploadType } from './useUpload'; |
46 | 47 | import { useMessage } from '/@/hooks/web/useMessage'; |
... | ... | @@ -55,9 +56,9 @@ |
55 | 56 | import { uploadApi } from '/@/api/sys/upload'; |
56 | 57 | import { isFunction } from '/@/utils/is'; |
57 | 58 | import { warn } from '/@/utils/log'; |
58 | - | |
59 | + import FileList from './FileList'; | |
59 | 60 | export default defineComponent({ |
60 | - components: { BasicModal, Upload, BasicTable, Alert }, | |
61 | + components: { BasicModal, Upload, Alert, FileList }, | |
61 | 62 | props: basicProps, |
62 | 63 | setup(props, { emit }) { |
63 | 64 | // 是否正在上传 |
... | ... | @@ -257,23 +258,25 @@ |
257 | 258 | } |
258 | 259 | } |
259 | 260 | |
260 | - const [registerTable] = useTable({ | |
261 | + // const [registerTable] = useTable({ | |
262 | + // columns: createTableColumns(), | |
263 | + // actionColumn: createActionColumn(handleRemove, handlePreview), | |
264 | + // pagination: false, | |
265 | + // inset: true, | |
266 | + // scroll: { | |
267 | + // y: 3000, | |
268 | + // }, | |
269 | + // }); | |
270 | + return { | |
261 | 271 | columns: createTableColumns(), |
262 | 272 | actionColumn: createActionColumn(handleRemove, handlePreview), |
263 | - pagination: false, | |
264 | - inset: true, | |
265 | - scroll: { | |
266 | - y: 3000, | |
267 | - }, | |
268 | - }); | |
269 | - return { | |
270 | 273 | register, |
271 | 274 | closeModal, |
272 | 275 | getHelpText, |
273 | 276 | getStringAccept, |
274 | 277 | getOkButtonProps, |
275 | 278 | beforeUpload, |
276 | - registerTable, | |
279 | + // registerTable, | |
277 | 280 | fileListRef, |
278 | 281 | state, |
279 | 282 | isUploadingRef, |
... | ... | @@ -295,5 +298,17 @@ |
295 | 298 | .ant-table-wrapper .ant-spin-nested-loading { |
296 | 299 | padding: 0; |
297 | 300 | } |
301 | + | |
302 | + &-toolbar { | |
303 | + display: flex; | |
304 | + align-items: center; | |
305 | + margin-bottom: 8px; | |
306 | + | |
307 | + &__btn { | |
308 | + margin-left: 8px; | |
309 | + text-align: right; | |
310 | + flex: 1; | |
311 | + } | |
312 | + } | |
298 | 313 | } |
299 | 314 | </style> | ... | ... |
src/components/Upload/src/UploadPreviewModal.vue
... | ... | @@ -7,13 +7,15 @@ |
7 | 7 | @register="register" |
8 | 8 | :showOkBtn="false" |
9 | 9 | > |
10 | - <BasicTable @register="registerTable" :dataSource="fileListRef" /> | |
10 | + <FileList :dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn" /> | |
11 | 11 | </BasicModal> |
12 | 12 | </template> |
13 | 13 | <script lang="ts"> |
14 | 14 | import { defineComponent, watch, ref, unref } from 'vue'; |
15 | 15 | |
16 | - import { BasicTable, useTable } from '/@/components/Table'; | |
16 | + // import { BasicTable, useTable } from '/@/components/Table'; | |
17 | + import FileList from './FileList'; | |
18 | + | |
17 | 19 | import { BasicModal, useModalInner } from '/@/components/Modal'; |
18 | 20 | import { previewProps } from './props'; |
19 | 21 | import { PreviewFileItem } from './types'; |
... | ... | @@ -22,7 +24,7 @@ |
22 | 24 | |
23 | 25 | import { createPreviewColumns, createPreviewActionColumn } from './data'; |
24 | 26 | export default defineComponent({ |
25 | - components: { BasicModal, BasicTable }, | |
27 | + components: { BasicModal, FileList }, | |
26 | 28 | props: previewProps, |
27 | 29 | setup(props, { emit }) { |
28 | 30 | const [register, { closeModal }] = useModalInner(); |
... | ... | @@ -71,17 +73,12 @@ |
71 | 73 | downloadByUrl({ url }); |
72 | 74 | } |
73 | 75 | |
74 | - const [registerTable] = useTable({ | |
75 | - columns: createPreviewColumns(), | |
76 | - pagination: false, | |
77 | - actionColumn: createPreviewActionColumn({ handleRemove, handlePreview, handleDownload }), | |
78 | - }); | |
79 | - | |
80 | 76 | return { |
81 | 77 | register, |
82 | 78 | closeModal, |
83 | 79 | fileListRef, |
84 | - registerTable, | |
80 | + columns: createPreviewColumns(), | |
81 | + actionColumn: createPreviewActionColumn({ handleRemove, handlePreview, handleDownload }), | |
85 | 82 | }; |
86 | 83 | }, |
87 | 84 | }); | ... | ... |
src/components/Upload/src/data.tsx
... | ... | @@ -12,7 +12,7 @@ export function createTableColumns(): BasicColumn[] { |
12 | 12 | width: 100, |
13 | 13 | customRender: ({ record }) => { |
14 | 14 | const { thumbUrl, type } = (record as FileItem) || {}; |
15 | - return <span>{thumbUrl ? <img style={{ maxWidth: '60px' }} src={thumbUrl} /> : type}</span>; | |
15 | + return <span>{thumbUrl ? <img style={{ maxWidth: '100%' }} src={thumbUrl} /> : type}</span>; | |
16 | 16 | }, |
17 | 17 | }, |
18 | 18 | { | ... | ... |
src/components/Upload/src/props.ts
1 | 1 | import type { PropType } from 'vue'; |
2 | +import { FileBasicColumn } from './types'; | |
2 | 3 | |
3 | 4 | export const basicProps = { |
4 | 5 | helpText: { |
... | ... | @@ -57,3 +58,18 @@ export const previewProps = { |
57 | 58 | default: () => [], |
58 | 59 | }, |
59 | 60 | }; |
61 | + | |
62 | +export const fileListProps = { | |
63 | + columns: { | |
64 | + type: [Array] as PropType<FileBasicColumn[]>, | |
65 | + default: null, | |
66 | + }, | |
67 | + actionColumn: { | |
68 | + type: Object as PropType<FileBasicColumn>, | |
69 | + default: null, | |
70 | + }, | |
71 | + dataSource: { | |
72 | + type: Array as PropType<any[]>, | |
73 | + default: null, | |
74 | + }, | |
75 | +}; | ... | ... |
src/components/Upload/src/types.ts
... | ... | @@ -23,3 +23,33 @@ export interface PreviewFileItem { |
23 | 23 | name: string; |
24 | 24 | type: string; |
25 | 25 | } |
26 | + | |
27 | +export interface FileBasicColumn { | |
28 | + /** | |
29 | + * Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config | |
30 | + * @type Function | ScopedSlot | |
31 | + */ | |
32 | + customRender?: Function; | |
33 | + /** | |
34 | + * Title of this column | |
35 | + * @type any (string | slot) | |
36 | + */ | |
37 | + title: string; | |
38 | + | |
39 | + /** | |
40 | + * Width of this column | |
41 | + * @type string | number | |
42 | + */ | |
43 | + width?: number; | |
44 | + /** | |
45 | + * Display field of the data record, could be set like a.b.c | |
46 | + * @type string | |
47 | + */ | |
48 | + dataIndex: string; | |
49 | + /** | |
50 | + * specify how content is aligned | |
51 | + * @default 'left' | |
52 | + * @type string | |
53 | + */ | |
54 | + align?: 'left' | 'right' | 'center'; | |
55 | +} | ... | ... |