bowen
2023-11-02 beed7f2e1172531fe691384a50c8b0457f3a80d8
提交 | 用户 | age
3f6920 1 <script lang="tsx">
V 2   import { fileListProps } from './props';
beed7f 3   import { isFunction, isDef } from '/@/utils/is';
B 4   import { useSortable } from '/@/hooks/web/useSortable';
3f6920 5   import { useModalContext } from '/@/components/Modal/src/hooks/useModalContext';
beed7f 6   import { defineComponent, CSSProperties, watch, nextTick, ref, onMounted } from 'vue';
3f6920 7
V 8   export default defineComponent({
9     name: 'FileList',
10     props: fileListProps,
beed7f 11     setup(props, { emit }) {
3f6920 12       const modalFn = useModalContext();
beed7f 13       const sortableContainer = ref<HTMLTableSectionElement>();
B 14
3f6920 15       watch(
V 16         () => props.dataSource,
17         () => {
18           nextTick(() => {
19             modalFn?.redoModalHeight?.();
20           });
56a966 21         },
3f6920 22       );
beed7f 23
B 24       if (props.openDrag) {
25         onMounted(() =>
26           useSortable(sortableContainer, {
27             ...props.dragOptions,
28             onEnd: ({ oldIndex, newIndex }) => {
29               // position unchanged
30               if (oldIndex === newIndex) {
31                 return;
32               }
33               const { onAfterEnd } = props.dragOptions;
34
35               if (isDef(oldIndex) && isDef(newIndex)) {
36                 const data = [...props.dataSource];
37
38                 const [oldItem] = data.splice(oldIndex, 1);
39                 data.splice(newIndex, 0, oldItem);
40
41                 nextTick(() => {
42                   emit('update:dataSource', data);
43
44                   isFunction(onAfterEnd) && onAfterEnd(data);
45                 });
46               }
47             },
48           }).initSortable(),
49         );
50       }
51
3f6920 52       return () => {
V 53         const { columns, actionColumn, dataSource } = props;
54         const columnList = [...columns, actionColumn];
55         return (
e7fbd7 56           // x scrollbar
B 57           <div class="overflow-x-auto">
58             <table class="file-table">
59               <colgroup>
3f6920 60                 {columnList.map((item) => {
e7fbd7 61                   const { width = 0, dataIndex } = item;
B 62                   const style: CSSProperties = {
63                     width: `${width}px`,
64                     minWidth: `${width}px`,
65                   };
66                   return <col style={width ? style : {}} key={dataIndex} />;
67                 })}
68               </colgroup>
69               <thead>
70                 <tr class="file-table-tr">
71                   {columnList.map((item) => {
72                     const { title = '', align = 'center', dataIndex } = item;
73                     return (
74                       <th class={['file-table-th', align]} key={dataIndex}>
75                         {title}
76                       </th>
77                     );
78                   })}
79                 </tr>
80               </thead>
beed7f 81               <tbody ref={sortableContainer}>
e7fbd7 82                 {dataSource.map((record = {}, index) => {
3f6920 83                   return (
e7fbd7 84                     <tr class="file-table-tr" key={`${index + record.name || ''}`}>
B 85                       {columnList.map((item) => {
86                         const { dataIndex = '', customRender, align = 'center' } = item;
87                         const render = customRender && isFunction(customRender);
88                         return (
89                           <td class={['file-table-td break-all', align]} key={dataIndex}>
90                             {render
91                               ? customRender?.({ text: record[dataIndex], record })
92                               : record[dataIndex]}
93                           </td>
94                         );
95                       })}
96                     </tr>
3f6920 97                   );
V 98                 })}
e7fbd7 99               </tbody>
B 100             </table>
101           </div>
3f6920 102         );
V 103       };
104     },
105   });
106 </script>
107 <style lang="less">
108   .file-table {
109     width: 100%;
110     border-collapse: collapse;
111
112     .center {
113       text-align: center;
114     }
115
116     .left {
117       text-align: left;
118     }
119
120     .right {
121       text-align: right;
122     }
123
124     &-th,
125     &-td {
126       padding: 12px 8px;
127     }
128
129     thead {
130       background-color: @background-color-light;
131     }
132
133     table,
134     td,
135     th {
136       border: 1px solid @border-color-base;
137     }
138   }
139 </style>