当前位置: 首页 > news >正文

Vue2文件上传相关

导入弹窗


<template><el-dialog:title="title":visible.sync="fileUploadVisible"append-to-bodyclose-on-click-modalclose-on-press-escapewidth="420px"><div v-if="showDatePicker">选择时间:<el-date-pickerv-model="dataDate"type="date"placeholder="选择日期"value-format="yyyy-MM-dd"format="yyyy-MM-dd"></el-date-picker></div><div class="my-upload"><el-uploadclass="upload-file-uploader"ref="fileUpload"multipledrag:action="uploadFileUrl":before-upload="handleBeforeUpload":file-list="fileList":limit="limit":on-error="handleUploadError":on-exceed="handleExceed":on-success="handleUploadSuccess":show-file-list="false":headers="headers":data="infoType"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em style="color: rgb(22, 93, 255)">点击上传</em></div></el-upload><!-- 文件列表 --><transition-groupclass="upload-file-list el-upload-list el-upload-list--text"name="el-fade-in-linear"tag="ul"><li:key="file.url"class="el-upload-list__item ele-upload-list__item-content"v-for="(file, index) in fileList"><el-link :href="file.url" :underline="false" target="_blank"><span class="el-icon-document"> {{ getFileName(file.name) }} </span></el-link><div class="ele-upload-list__item-content-action"><el-link:underline="false"@click="handleDelete(index)"type="danger">删除</el-link></div></li></transition-group></div><div style="text-align: center; padding: 15px">点击右侧按钮,下载导入模板<span class="import-text" v-if="showDownLoad" @click="onDownLoad">下载</span></div><div class="tip-text" v-if="tipText"><span>特别提醒:</span>{{ tipText }}</div></el-dialog>
</template>
<script>
import dayjs from "dayjs";
import { saveAs } from "file-saver";
import { getToken } from "@/utils/auth";export default {props: {title: {type: String,default: "导入",},tipText: {type: String,default: "",},// 值value: [String, Object, Array],// 数量限制limit: {type: Number,default: 99,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["xls", "xlsx"],// default: () => ["png", "jpg", "jpeg"],},// 下载模版apidownloadApi: {type: Function,default: () => {console.log("[  ] >", "downloadApi");},},// 下载模板标题downloadTitle: {type: String,default: "导入模板",},// 导入apiimportApi: {type: Function,default: () => {console.log("[  ] >", "importApi");},},// 是否真是下载模板showDownLoad: {type: Boolean,default: true,},showDatePicker: {type: Boolean,default: false,},// 模板下载地址uploadUrl: { type: String, default: "" },// 导入需要的InfoTypeinfoType: {type: Object,default: () => {},},},data() {return {number: 0,uploadList: [],uploadFileUrl: process.env.VUE_APP_BASE_API + "/file/upload", // 上传文件服务器地址headers: {Authorization: "Bearer " + getToken(),},fileList: [],fileUploadVisible: false,file: null,dataDate: "",};},mounted() {},watch: {value: {handler(val) {if (val) {let temp = 1;// 首先将值转为数组const list = Array.isArray(val) ? val : this.value.split(",");// 然后将数组转为对象数组this.fileList = list.map((item) => {if (typeof item === "string") {item = { name: item, url: item };}item.uid = item.uid || new Date().getTime() + temp++;return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true,},},methods: {onShow() {this.fileUploadVisible = true;console.log(process.env.VUE_APP_BASE_API + "/file/upload");this.dataDate = "";},// 下载模版onDownLoad() {this.downloadApi().then((res) => {const blob = new Blob([res]);saveAs(blob, `${this.downloadTitle}.xlsx`);});},// 上传前校检格式和大小handleBeforeUpload(file) {if (this.showDatePicker && this.dataDate == "") {this.$message.warning("请先选择日期");} else {// 校检文件类型if (this.fileType) {const fileName = file.name.split(".");const fileExt = fileName[fileName.length - 1];const isTypeOk = this.fileType.indexOf(fileExt) >= 0;if (!isTypeOk) {this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);return false;}}this.file = file;this.$modal.loading("正在上传文件,请稍候...");this.number++;return true;}},// 文件个数超出handleExceed() {this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);},// 上传失败handleUploadError(err) {this.$modal.msgError("上传文件失败,请重试");this.$modal.closeLoading();},// 上传成功回调handleUploadSuccess(res, file) {if (this.showDatePicker && this.dataDate == "") {} else {if (res.code == 200) {const formData = new FormData();formData.append("file", this.file);if (this.showDatePicker) {formData.append("dataDate", this.dataDate);}this.importApi(formData).then((res) => {if (res.code == 0 || res.code == 200) {this.$message.success("导入成功");this.uploadList = [];this.fileList = [];this.fileUploadVisible = false;this.$modal.closeLoading();this.$emit("getList");}}).catch(() => {this.$modal.closeLoading();});return;}this.$modal.msgError("上传文件失败,请重试");this.$modal.closeLoading();}},// 删除文件handleDelete(index) {this.fileList.splice(index, 1);this.$emit("input", this.listToString(this.fileList));},// 上传结束处理uploadedSuccessfully() {if (this.number > 0 && this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 获取文件名称getFileName(name) {// 如果是url那么取最后的名字 如果不是直接返回if (name?.lastIndexOf("/") > -1) {return name.slice(name.lastIndexOf("/") + 1);} else {return name;}},// 对象转成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {strs += list[i].url + separator;}return strs != "" ? strs.substr(0, strs.length - 1) : "";},},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__header > .el-dialog__title {font-weight: 600 !important;
}.import-text {color: rgb(22, 93, 255);text-align: center;font-size: 14px;cursor: pointer;
}.my-upload {margin-top: 20px;display: flex;justify-content: center;.el-icon-upload {color: rgb(22, 93, 255);font-size: 100px;}
}.tip-text {padding: 0 10px;margin-top: 20px;color: rgb(241, 51, 51);
}.upload-file-uploader {margin-bottom: 5px;
}.upload-file-list .el-upload-list__item {border: 1px solid #e4e7ed;line-height: 2;margin-bottom: 10px;position: relative;
}.upload-file-list .ele-upload-list__item-content {display: flex;justify-content: space-between;align-items: center;color: inherit;
}.ele-upload-list__item-content-action .el-link {margin-right: 10px;
}:v-deep .el-upload,
.el-upload--text {// margin: 0 auto !important;width: 100% !important;
}
</style>

弹窗使用

 <!-- 导入 -->
<FileUploadref="fileUpload"title="导入数据":importApi="importRealApi":onReset="getRealList"@getList="getList":infoType="infoType":downloadApi="downRealTempleteApi":showDatePicker="true":tipText="tipText"downloadTitle="房产交易信息导入模板"
/>

1.为什么要进行 const formData = new FormData() 处理

HTTP 请求中,文件不能直接作为普通文本字段发送,需要以二进制流的形式上传。FormData 专门用于构造包含文件的表单数据,浏览器会自动将其编码成 multipart/form-data 格式,符合文件上传的标准

2.multipart/form-data 格式是什么  

multipart/form-data 是一种专门为上传文件设计的 HTTP 请求编码格式,它通过分隔符将多个字段(包括文件)分开,保证文件数据能被正确传输和解析,是文件上传的标准方式。

http://www.lryc.cn/news/598680.html

相关文章:

  • 零知识证明
  • vs2019 创建MFC ActiveX的详细步骤
  • Qt WebEngine Widgets的使用
  • 爬虫基础概念
  • 在Ubuntu上使用QEMU学习RISC-V程序(1)起步第一个程序
  • linux C -glib库的基本使用
  • Windows环境下 Go项目迁移至Ubuntu(WSL) 以部署filebeat为例
  • 如何在 Ubuntu 24.04 服务器或桌面版上安装和使用 gedit
  • 深度分析Java内存回收机制
  • 跨境支付入门~国际支付结算(电商篇)
  • unordered_map和unordered_set特性以及解决哈希冲突
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-19,(知识点:PCB布局布线的设计要点)
  • DevOps 完整实现指南:从理论到实践
  • LeetCode 23:合并 K 个升序链表
  • 【已解决】YOLO11模型转wts时报错:PytorchStreamReader failed reading zip archive
  • 医疗AI轻量化部署方案的深度梳理与优化路径判研
  • 基于Qt的仿QQ聊天系统设计
  • Ethereum: 区块链浏览器,我们的“天眼”
  • 力扣 hot100 Day54
  • 【开源】WpfMap:一个基于WPF(Windows Presentation Foundation)技术构建的数据可视化大屏展示页面
  • JS对象键的秘密:数字变字符串?
  • 【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构
  • 应急响应】Linux 自用应急响应工具发版 v6.0(LinuxGun)
  • redis 源码阅读
  • 完整指南:使用Apache htpasswd为Chronograf配置基础认证及功能详解
  • AWS S3 生命周期管理最佳实践:IoT Core 日志的智能存储优化
  • 【水文水资源] SWAT、AquaCrop模型、HYPE、Aquatox、Delft3D、FVCOM、3s水文、
  • 数据推荐丨海天瑞声7月数据集上新啦!
  • 用python自动标注word试题选项注意事项
  • 基于k2-icefall实践Matcha-TTS中文模型训练2