Vue3 + TS 实现批量拖拽 文件夹和文件 组件封装

打印 上一主题 下一主题

主题 1588|帖子 1588|积分 4764

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、html 代码:

代码中的表格引入了 vxe-table 插件
<Tag /> 是自己封装的说明组件
表格列表这块我使用了插槽来增长扩展性,可根据自己需求,在组件外部做调解
  1. <template>
  2.     <div class="dragUpload">
  3.         <el-dialog v-model="data.visible"
  4.             width="35%"
  5.             center
  6.             :draggable="draggable"
  7.             :destroy-on-close="true"
  8.             :close-on-click-modal="false"
  9.             :close-on-press-escape="false"
  10.             :before-close="closeDialogFn"
  11.         >
  12.             <template #header>
  13.                 <h3>
  14.                     {
  15.   
  16.   { fileData.step === 2 ? '提示:文件超出大小限制' : '拖拽上传'}}
  17.                 </h3>
  18.             </template>
  19.             <!-- 文件上传区域 -->
  20.             <div class="drag-box"
  21.                 v-if="fileData.step === 1"
  22.                 @dragover="handleDragOver"
  23.                 @dragleave="handleDragOver"
  24.                 @drop="handleDrop"
  25.             >
  26.                 <div class="div-text" >
  27.                     <div class="drag-tip">
  28.                         拖拽文件至此区域
  29.                         <span class="click-txt" @click="toUploadFloder">点击上传</span>
  30.                     </div>
  31.                     <div class="btn-wrap">
  32.                         <el-button v-if="singleFile" @click="toUploadFile">上传文件</el-button>
  33.                         <el-button @click="toUploadFloder">上传文件夹</el-button>
  34.                         <input
  35.                             v-if="singleFile"
  36.                             :style="{ display: 'none' }"
  37.                             type="file"
  38.                             ref="fileUploadRef"
  39.                             @change="handleFileChange"
  40.                             multiple
  41.                         />
  42.                         <input
  43.                             :style="{ display: 'none' }"
  44.                             type="file"
  45.                             ref="fileUploadFloderRef"
  46.                             @change="handleFloderChange"
  47.                             webkitdirectory
  48.                             multiple
  49.                         />
  50.                     </div>
  51.                 </div>
  52.             </div>
  53.             <!-- 超出限制后,展示的列表 -->
  54.             <div v-if="fileData.step === 2">
  55.                 <!-- 组件内默认展示 -->
  56.                 <div class="max-h311" v-if="!openSlot">
  57.                     <vxe-table
  58.                         :data="fileData.goBeyondTable"
  59.                         height="100%"
  60.                         :checkbox-config="{
  61.                             showHeader: true,
  62.                             trigger: 'cell'
  63.                         }"
  64.                     >
  65.                         <template #empty>
  66.                             <div class="no-data-box">
  67.                                 <i class="icon_noData"></i>
  68.                                 <div class="m-t6">暂无数据</div>
  69.                             </div>
  70.                         </template>
  71.                         <vxe-column min-width="180" :title="`${data.fileName || 'SPU'}文件名`">
  72.                             <template #default="{ row }">
  73.                                 {
  74.   
  75.   { row[fileData.firstFileName] ? row[fileData.firstFileName] : '--' }}
  76.                             </template>
  77.                         </vxe-column>
  78.                         <vxe-column min-width="111" title="大小">
  79.                             <template #default="{ row }">
  80.                                 {
  81.   
  82.   { row.size ? row.size : '--' }} MB
  83.                             </template>
  84.                         </vxe-column>
  85.                         <vxe-column width="100" title="操作" :visible="fileData.goBeyondTable.length > 1">
  86.                             <template #default="{ $rowIndex, row }">
  87.                                 <el-tooltip
  88.                                     content="移除"
  89.                                     placement="top"
  90.                                     :hide-after="0"
  91.                                 >
  92.                                     <a class="icon_delete f-s18"
  93.                                         href="javscript:"
  94.                                         @click="handleDelete($rowIndex, row)">
  95.                                     </a>
  96.                                 </el-tooltip>
  97.                             </template>
  98.                         </vxe-column>
  99.                     </vxe-table>
  100.                 </div>
  101.                 <!-- 插槽,可使用外部传入 -->
  102.                 <template v-else>
  103.                     <slot name="errorTable"></slot>
  104.                 </template>
  105.             </div>
  106.             <Tag class="m-t12"
  107.                 v-if="data.fileSize"
  108.                 :content="fileData.step === 1 ? `上传文件总大小不能超过 ${data.fileSize} MB` : `上传文件总大小不能超过 ${data.fileSize} MB,当前文件总大小 ${fileData.allSize} MB`"
  109.             />
  110.             <template #footer v-if="!autoUpload || fileData.step === 2">
  111.                 <div class="dialog-footer">
  112.                     <el-button @click="closeDialogFn">取消</el-button>
  113.                     <!-- 默认使用内部提交逻辑 -->
  114.                     <template v-if="!openSlot">
  115.                         <el-button type="primary" @click="handleUploadToServer(true)">
  116.                             {
  117.   
  118.   { fileData.step === 1 ? '上传' : '提交' }}
  119.                         </el-button>
  120.                     </template>
  121.                     <!-- 开启插槽,则使用外部自定义 -->
  122.                     <template v-else>
  123.                         <slot name="footerBtn"></slot>
  124.                     </template>
  125.                 </div>
  126.             </template>
  127.         </el-dialog>
  128.     </div>
  129. </template>
复制代码

二、js 代码:

目前支持校验上传的文件类型有三种:
image:图片类型;video:视频类型;excel:表格类型
这块重要思路是:将文件夹判定后举行递归,获取出文件夹中的文件出来,末了雷同单个文件上传,然后将文件流举行遍历 append 进创建的 FormData 对象。具体方法看:readFiles() 和 handleUploadToServer()
  1. <script lang="ts" setup>
  2. import { reactive, ref, getCurrentInstance } from 'vue';
  3. const { proxy }: any = getCurrentInstance();
  4. const $tool = proxy.$tool;
  5. const props = defineProps({
  6.     // 组件参数配置
  7.     data: {
  8.         type: Object,
  9.         default: () => ({
  10.             // fileSize: 100, // 文件大小限制
  11.             /*** type 对象为空或者不传,则不限制上传类型 */
  12.             // type: {   
  13.             //     自定义上传的文件类型 = image:图片类型;video:视频类型;excel:表格类型
  14.             //     image: ['png', 'jpg', 'jpeg'],
  15.             //     video: ['mp4', 'avi', 'mov'],
  16.             //     excel: ['xlsx', 'xls']
  17.             // },
  18.             /*** 格式错误自定义提示:根据 type 来,但格式需要写成 ${'type中的key'},因组件内部代码采用:查找 ${} 进行替换;不传则使用组件内默认提示 */
  19.             // formatMessage: {
  20.             //     'image': '只支持上传图片:${image} 格式',
  21.             //     'image,video': '支持上传图片:${image} 格式,视频:${video} 格式',
  22.             //     'image,video,excel': '支持上传图片:${image} 格式,视频:${video} 格式,Excel文件:${excel} 格式'
  23.             // }
  24.             // limit: 0, // 允许上传文件的最大数量,0或不传默认无限制
  25.             // fileName: '', // 超出后列表展示的文件名:不传默认为SPU
  26.         }),
  27.     },
  28.     // 是否支持窗口拖拽,默认true
  29.     draggable: {
  30.         type: Boolean,
  31.         default: true
  32.     },
  33.     // 是否自动上传文件,默认true
  34.     autoUpload: {
  35.         type: Boolean,
  36.         default: true
  37.     },
  38.     // 是否支持打开 file 单文件上传,不传默认false
  39.     singleFile: {
  40.         type: Boolean,
  41.         default: false
  42.     },
  43.     //是否需要开启:列表上传失败 和 提交按钮插槽;默认不开启,展示组件内的失败列表 和 提交逻辑
  44.     openSlot: {
  45.         type: Boolean,
  46.         default: false
  47.     }
  48. });
  49. /**
  50. * @param dragUploadAxiosFn 上传参数抛出,外部做处理,不与组件内部逻辑耦合
  51. * @param dragUploadErrorTable 超出限制后,展示的列表插槽抛出,外部做处理,不与组件内部逻辑耦合
  52. */
  53. const emit = defineEmits(['dragUploadAxiosFn', 'dragUploadErrorTable']);
  54. const fileUploadRef = ref();
  55. const fileUploadFloderRef = ref();
  56. const fileData: any = reactive({
  57.     step: 1, // 步骤: 1:文件拖拽上传;2:文件超出提示
  58.     uploadList: [], //上传的文件列表
  59.     waitUploadList: [], //存储待上传的文件列表
  60.     fileSizeList: [], //存储遍历出来文件里面所有的图片路径及大小
  61.     goBeyondTable: [], //超出限制后,将遍历项还原成文件夹项展示的列表
  62.     allSize: 0, //文件总大小 MB
  63.     firstFileName: 'pathName0' //第一列字段:key
  64. });
  65. /*文件上传input*/
  66. const toUploadFile = () => {
  67.     fileUploadRef.value.click();
  68. };
  69. /*文件夹上传input*/
  70. const toUploadFloder = () => {
  71.     fileUploadFloderRef.value.click();
  72. };
  73. /*选择文件改变*/
  74. const handleFileChange = (e: any) => {
  75.     if (e.target.files) {
  76.         let filesList: any = Array.from(e.target.files);
  77.         filesList.forEach((item: any) => {
  78.             let size = item.size / 1024 / 1024;
  79.             fileData.allSize += size;
  80.             let obj: any = getPath(item.name);
  81.             changeFileSizeList(item, obj);
  82.         });
  83.         fileData.allSize = fileData.allSize.toFixed(2); // 文件总大小 MB
  84.         fileData.waitUploadList = filesList;
  85.         if (!fileLimitFn(fileData.fileSizeList)) return; // 校验方法
  86.         handleUploadToServer(); //上传文件到服务器
  87.     }
  88. };
  89. /*文件夹目录上传*/
  90. const handleFloderChange = (e: any) => {
  91.     if (e.target.files) {
  92.         let filesList: any = Array.from(e.target.files);
  93.         filesList.forEach((item: any) => {
  94.             let size = item.size / 1024 / 1024;
  95.             fileData.allSize += size;
  96.             let obj: any = getPath(item.webkitRelativePath); // 通过路径获取名称方法
  97.             changeFileSizeList(item, obj);
  98.         });
  99.         filesList.reverse(); // 反转数组,保证最先选择的文件排在最后面
  100.         fileData.allSize = fileData.allSize.toFixed(2); // 文件总大小 MB
  101.         fileData.waitUploadList = filesList;
  102.         if (!fileLimitFn(fileData.fileSizeList)) return; // 校验方法
  103.         handleUploadToServer(); //上传文件到服务器
  104.     }
  105. };
  106. // 拖放进入目标区域
  107. const handleDragOver = (event) => {
  108.     event.preventDefault();
  109. };
  110. // 拖拽放置
  111. const handleDrop = async (event) => {
  112.     event.preventDefault();
  113.     const files = [];
  114.     const promises: any[] = [];
  115.     for (const item of event.dataTransfer.items) {
  116.         const entry: any = item.webkitGetAsEntry();
  117.         
  118.         if (!entry.isDirectory && !props.singleFile) {
  119.             proxy.$message.error(`只支持文件夹上传,不支持单个文件上传!`);
  120.             return;
  121.         }
  122.         promises.push(readFiles(entry));
  123.     }
  124.     const resultFilesArrays = await Promise.all(promises); // 等待所有文件读取完成
  125.     fileData.waitUploadList = resultFilesArrays.flat();
  126.     if (!fileLimitFn(fileData.fileSizeList)) return; // 校验方法
  127.     handleUploadToServer(); //上传文件到服务器
  128. };
  129. //文件各种限制判断方法封装
  130. const fileLimitFn = (fileSizeList: any) => {
  131.     //文件类型判断和格式限制
  132.     if (props.data.type) {
  133.         if (!testingFileType(fileSizeList)) return false;
  134.     }
  135.     //文件数量超出限制
  136.     if (props.data.limit && props.data.limit !== 0) {
  137.         if (!fileLimit(fileSizeList)) return false;
  138.     }
  139.     //文件大小超出限制
  140.     if (props.data.fileSize) {
  141.         if (!fileSizeLimit(fileSizeList)) {
  142.             fileData.goBeyondTable = getGoBeyondTable(fileSizeList);
  143.             fileData.step = 2;
  144.             return false;
  145.         }
  146.     }
  147.     return true;
  148. };
  149. /**
  150. * 验证文件类型是否为允许的上传的类型
  151. * @param fileSizeList 文件列表
  152. * @param type  image:图片类型;video:视频类型;excel:表格类型
  153. * @param formatMessage 外部传入的自定义提示信息,替换默认提示信息或者新增进入提示信息
  154. * @returns 如果文件类型不符合要求,返回 false;否则返回 true
  155. */
  156. const testingFileType = (fileSizeList: any) => {
  157.     let type: any = props.data.type;
  158.     if (Object.keys(type).length === 0) return true; // type 对象为空或者不传,则不限制上传类型
  159.     // 使用 Object.values 获取对象值的数组,然后使用 flatMap 合并所有数组
  160.     const typeList = Object.values(type).flatMap((array: any) => array);
  161.     // 获取所有键的字符串表示,例如 "image,video,excel"
  162.     const keysString = Object.keys(type).join(',');
  163.     const messageTemplates = {
  164.         'image': '只支持上传图片:${image} 格式',
  165.         'video': '只支持上传视频:${video} 格式',
  166.         'excel': '只支持上传Excel文件:${excel} 格式',
  167.         'image,video': '支持上传图片:${image} 格式,视频:${video} 格式',
  168.         'image,excel': '支持上传图片:${image} 格式,Excel文件:${excel} 格式',
  169.         'video,excel': '支持上传视频:${video} 格式,Excel文件:${excel} 格式',
  170.         'image,video,excel': '支持上传图片:${image} 格式,视频:${video} 格式,Excel文件:${excel} 格式'
  171.     };
  172.     // 外部传入:自定义提示信息替换成外部传入的
  173.     if (props.data.formatMessage && Object.keys(props.data.formatMessage).length) {
  174.         let msg: any = props.data.formatMessage;
  175.         for (const key in msg) {
  176.             if (messageTemplates.hasOwnProperty(key)) {
  177.                 // 如果 messageTemplates 中存在该键,则替换其值
  178.                 messageTemplates[key] = msg[key];
  179.             } else {
  180.                 // 不存在则增加进去
  181.                 messageTemplates[key] = msg[key];
  182.             }
  183.         }
  184.     }
  185.     // 正则:查找 ${},后进行替换
  186.     let message: string = '';
  187.     if (messageTemplates[keysString]) {
  188.         message = messageTemplates[keysString].replace(/\$\{(\w+)\}/g, (_, match) => type[match].join(', '));
  189.     } else {
  190.         message = `不支持上传该类型的文件:${keysString},请重新上传!`;
  191.     }
  192.     //过滤不符合要求的文件类型
  193.     let filterList: any = fileSizeList.filter((item: any) => !typeList.includes(item.type));
  194.     if (filterList.length) {
  195.         //错误的文件,不管里面有没有正确格式的,一律清除
  196.         fileData.fileSizeList = [];
  197.         fileData.allSize = 0;
  198.         proxy.$message.error(message);
  199.         return false;
  200.     };
  201.     return true;
  202. };
  203. //文件数量超出限制
  204. const fileLimit = (fileSizeList: any) => {
  205.     if (fileSizeList.length > props.data.limit) {
  206.         proxy.$message.error(`文件数量不能超过 ${props.data.limit} 个,请重新上传!`);
  207.         fileData.fileSizeList = [];
  208.         return false;
  209.     }
  210.     return true;
  211. };
  212. //文件超出限制
  213. const fileSizeLimit = (fileSizeList: any) => {
  214.     let allSize = fileSizeList.reduce((accumulator, currentValue) => {
  215.         if (currentValue) {
  216.             return accumulator + currentValue.size;
  217.         }
  218.         return accumulator;
  219.     }, 0);
  220.     let fileSize = props.data.fileSize * 1024 * 1024;
  221.     fileData.allSize = (allSize / 1024 / 1024).toFixed(2); //存储文件总大小 MB
  222.     if (allSize > fileSize) {
  223.         proxy.$message.error(`文件总大小不能超过 ${props.data.fileSize} MB,请重新上传!`);
  224.         emit('dragUploadErrorTable', fileData);
  225.         return false;
  226.     }
  227.     return true;
  228. };
  229. // 操作数据:文件超出后,展示的列表
  230. const getGoBeyondTable = (fileSizeList: any) => {
  231.     // 遍历,相同第一列为一项,size累加
  232.     let result: any = fileSizeList.reduce((accumulator, current) => {
  233.         if (accumulator[current[fileData.firstFileName]]) { //如果已经存在,则累加size
  234.             accumulator[current[fileData.firstFileName]].size += current.size;
  235.         } else {
  236.             accumulator[current[fileData.firstFileName]] = { ...current };
  237.         }
  238.         return accumulator;
  239.     }, {});
  240.    
  241.     // 将结果对象转换回数组
  242.     result = Object.values(result);
  243.     // 处理size为MB单位
  244.     result.forEach((item: any) => {
  245.         item.size = (item.size / 1024 / 1024).toFixed(2);
  246.     });
  247.     return result;
  248. };
  249. //移除超出文件列表的项
  250. const handleDelete = (rowIndex: number, row: any) => {
  251.     fileData.goBeyondTable.splice(rowIndex, 1);
  252.     fileData.allSize = (fileData.allSize - row.size).toFixed(2); //更新总大小MB
  253.     fileData.fileSizeList = fileData.fileSizeList.filter((item: any) => item[fileData.firstFileName] !== row[fileData.firstFileName]);
  254.     fileData.waitUploadList = fileData.waitUploadList.filter((item: any) => item[fileData.firstFileName] !== row[fileData.firstFileName]);
  255. };
  256. /*请求上传到服务器*/
  257. const handleUploadToServer = (click?: boolean) => {
  258.     let autoUpload: boolean = props.autoUpload;
  259.     if (click && fileData.step === 1) autoUpload = true; //手动上传
  260.     if (!autoUpload && fileData.step === 1) return; //不自动上传,则不执行
  261.     fileData.uploadList = fileData.waitUploadList;
  262.     // 再次提交时验证文件大小是否超出限制
  263.     if (click && fileData.step === 2 && fileData.allSize > props.data.fileSize) {
  264.         proxy.$message.error(`文件总大小不能超过 ${props.data.fileSize} MB`);
  265.         return;
  266.     }
  267.    
  268.     let formData = new FormData();
  269.     fileData.uploadList.forEach((item: any) => {
  270.         formData.append(`${item.filePathName}`, item);
  271.     });
  272.    
  273.     // // 遍历FormData对象并打印其内容:查看FormData对象数据是否正确
  274.     // for (let [key, value] of formData.entries()) {
  275.     //     console.log(`${key}: ${value}`);
  276.     // }
  277.     emit('dragUploadAxiosFn', formData); //上传参数抛出,外部做操作,不在组件做耦合
  278. };
  279. //此方法:如果是文件夹,则会递归调用自己,所以最后都会走 else 的逻辑
  280. const readFiles = async (item: any) => {
  281.     if (item.isDirectory) {
  282.         // 是一个文件夹
  283.         const directoryReader = item.createReader();
  284.         // readEntries是一个异步方法
  285.         const entries: any[] = await new Promise((resolve, reject) => {
  286.             directoryReader.readEntries(resolve, reject);
  287.         });
  288.         let files = [];
  289.         for (const entry of entries) {
  290.             const resultFiles: any = await readFiles(entry);
  291.             files = files.concat(resultFiles);
  292.         }
  293.         return files;
  294.     } else {
  295.         // file也是一个异步方法
  296.         const file = await new Promise((resolve, reject) => {
  297.             item.file(resolve, reject);
  298.         });
  299.         let obj: any = getPath(item.fullPath); //通过路径获取名称方法
  300.         changeFileSizeList(file, obj);
  301.         return [file];
  302.     }
  303. };
  304. //更改 fileData.fileSizeList 的值:公共
  305. const changeFileSizeList = (file: any, obj: any) => {
  306.     try {
  307.         file.filePathName = obj.filePathName; //添加路径名称
  308.         file[fileData.firstFileName] = obj.pathObj[fileData.firstFileName]; //添加第一列文件名
  309.         file.pathObj = obj.pathObj;
  310.         let index = file.name.lastIndexOf('.');
  311.         fileData.fileSizeList.push({ //添加图片路径、大小、名称
  312.             filePathName: obj.filePathName,
  313.             size: file.size,
  314.             type: file.name.substring(index + 1),
  315.             ...obj.pathObj
  316.         });
  317.     } catch {
  318.         proxy.$message.error(`文件读取路径失败,请重新上传文件!`);
  319.     }
  320. };
  321. //通过路径获取名称方法:公共
  322. const getPath = (path: string) => {
  323.     try {
  324.         let filePathName: any = path;  // 传给后端的全路径
  325.         if (path.startsWith('/')) { // 如果路径以斜杠开头,则删除第一个斜杠
  326.             filePathName = path.slice(1);
  327.         }
  328.         let parts = filePathName.split('/'); // 路径分割成数组
  329.         let pathObj = {}; // 存储每个部分
  330.         for (let i = 0; i < parts.length; i++) {
  331.             if (parts[i] !== '') { // 跳过空字符串(如果路径以 / 开头或结尾)
  332.                 pathObj['pathName' + (i)] = parts[i];
  333.             }
  334.         }
  335.         return {
  336.             filePathName: filePathName,
  337.             pathObj: pathObj
  338.         }
  339.     } catch {
  340.         proxy.$message.error(`文件读取路径失败,请重新上传文件!`);
  341.     }
  342. };
  343. //关闭事件
  344. const closeDialogFn = () => {
  345.     if (fileData.step === 1) {
  346.         props.data.visible = false; //关闭弹窗
  347.         return;
  348.     }
  349.     proxy.$messageBox({
  350.         title: '关闭',
  351.         message: '关闭后不会保留您所做的更改,确定关闭吗?',
  352.         callback: (value: string) => {
  353.             //confirm=确认;cancel=取消
  354.             if (value === 'confirm') {
  355.                 fileData.step = 1;
  356.                 props.data.visible = false; //关闭弹窗
  357.             }
  358.         }
  359.     });
  360. };
  361. </script>
复制代码
三、css 代码:

  1. <style lang="scss" scoped>
  2. .drag-box {
  3.     position: relative;
  4.     .progress-bar {
  5.         position: absolute;
  6.         z-index: 100;
  7.         width: 100%;
  8.         top: 0;
  9.         left: 0px;
  10.         right: 0px;
  11.         bottom: -5px;
  12.         display: flex;
  13.         justify-content: center;
  14.         align-items: center;
  15.         background-color: rgba(255, 255, 255, 0.8);
  16.         :deep(.el-progress.el-progress--line) {
  17.             width: 100%;
  18.             margin-left: 10px;
  19.         }
  20.     }
  21.     .uploaded-list-wrap {
  22.         max-height: 200px;
  23.         overflow-y: auto;
  24.         .uploaded-item {
  25.             display: flex;
  26.             justify-content: space-between;
  27.             align-items: center;
  28.             cursor: pointer;
  29.             margin-bottom: 3px;
  30.             .text-content {
  31.                 width: 80%;
  32.                 white-space: nowrap;
  33.                 overflow: hidden;
  34.                 text-overflow: ellipsis;
  35.             }
  36.             .icon {
  37.                 width: 25px;
  38.                 height: 25px;
  39.             }
  40.             .success-icon {
  41.                 display: block;
  42.             }
  43.             .delete-icon {
  44.                 display: none;
  45.             }
  46.             &:hover {
  47.                 .success-icon {
  48.                     display: none;
  49.                 }
  50.                 .delete-icon {
  51.                     display: block;
  52.                 }
  53.             }
  54.         }
  55.     }
  56. }
  57. .div-text {
  58.     width: 100%;
  59.     height: 250px;
  60.     border: 1px dashed #409effc2;;
  61.     border-radius: 10px;
  62.     box-sizing: border-box;
  63.     display: flex;
  64.     flex-direction: column;
  65.     justify-content: center;
  66.     align-items: center;
  67.     font-size: 18px;
  68.     background-color: #cccccc1c;
  69.     .click-txt {
  70.         color: #409effc2;;
  71.         cursor: pointer;
  72.     }
  73.     .btn-wrap {
  74.         margin-top: 20px;
  75.     }
  76. }
  77. .min-h311 {
  78.     min-height: 311px;
  79. }
  80. .max-h311 {
  81.     max-height: 311px;
  82. }
  83. :deep(.el-dialog .el-dialog__header) {
  84.     padding: 12px 30px;
  85.     display: flex;
  86.     justify-content: space-between;
  87. }
  88. :deep(.el-dialog .el-dialog__body) {
  89.     padding: 8px 30px 11px;
  90. }
  91. :deep(.el-dialog .el-dialog__footer) {
  92.     padding: 6px 30px 14px;
  93. }
  94. .dialog-footer {
  95.     display: flex;
  96.     justify-content: flex-end;
  97. }
  98. .color-409 {
  99.     color: #409effc2;;
  100. }
  101. </style>
复制代码
四、vue 页面中使用:

  1. <!-- 拖拽上传 -->
  2. <DragUpload v-if="dragUpload.visible"
  3.             :data="dragUpload"
  4.             @dragUploadAxiosFn="dragUploadAxiosFn"
  5. />
复制代码
  1. const dragUpload: any = reactive({
  2.     visible: false,
  3.     fileSize: 100, // 单位字节 MB
  4.     type: { //定义上传的文件类型 = image:图片类型;video:视频类型;excel:表格类型
  5.         image: ['png', 'jpg', 'jpeg'],
  6.     },
  7.     formatMessage: {
  8.         'image': '自定义外部传入${image} 格式',
  9.     },
  10.     fileName: 'SPU' // 超出后列表展示的文件名
  11. });
复制代码
 五、上传到后端接口的参数:


 六、效果图,如下:



七、额外补充,后端接收文件流的方法: 




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81429

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表