Bootstrap

封装el-upload实现文件上传弹出框和进度条展示

使用若依分离版的框架,基于element-ui的上传组件封装

1、使用效果

在这里插入图片描述

2、组件封装

(完整代码,放到指定文件夹,注意调用该组件时位置的获取)

<template>
	<div>
		<div class="tablebox">
			<el-table :data="upload.fileList" max-height="280" style="width: 100%">
				<el-table-column prop="name" align="center" label="文件名"></el-table-column>
				<el-table-column prop="size" align="center" label="大小">
					<template slot-scope="scope">
						<div>{{ (scope.row.size / 1024 / 1024).toFixed(2) }} MB</div>
					</template>
				</el-table-column>
				<el-table-column prop="percentage" align="center" label="进度">
					<template slot-scope="scope">
						<el-progress :text-inside="true" :stroke-width="15" :percentage="scope.row.percentage"
							:format="percentageFormat"></el-progress>
					</template>
				</el-table-column>
				<el-table-column prop="size" align="center" label="操作">
					<template slot-scope="scope">
						<i class="el-icon-delete" style="color:red" v-if="scope.row.percentage != 100"
							@click="deleteDocument(scope)"></i>
					</template>
				</el-table-column>
			</el-table>
		</div>
		<!-- 上传组件 -->
		<el-upload class="upload-demo box_upload" multiple :auto-upload="false" :show-file-list="false" ref="upload"
			:action="upload.url" :headers="upload.headers" :on-preview="handlePreview" :on-remove="handleRemove"
			:on-progress="handleProgress" :on-success="handleAvatarSuccess" :on-error="handleVideoError"
			:before-remove="beforeRemove" :on-change="changeimg" :file-list="upload.fileList" :accept="upload.accept">
			<el-button class="primary">选择本地文件</el-button>
		</el-upload>
		<span slot="footer" class="dialog-footer">
			<el-button @click="cancel">关 闭</el-button>
			<el-button class="primary" @click="submitUpload">确 定</el-button>
		</span>
	</div>
</template>

<script>
	import {
		getToken
	} from "@/utils/auth";
	export default {
		name: "FileUploadDig",
		props: {
			upload: {
				type: Object,
				default: () => {
					return this.upload1;
				}
			},
			fileOpen: {
				type: Boolean,
				default: () => {
					return false;
				}
			}
		},
		data() {
			return {
				tableDataES: [],
				uploadCount: 0,
				// 上传参数
				upload1: {
					// 是否禁用上传
					isUploading: false,
					// 设置上传的请求头部
					headers: {
						Authorization: "Bearer " + getToken()
					},
					// 上传的地址
					url: process.env.VUE_APP_BASE_API + "/common/upload",
					// 上传的文件列表
					fileList: [],
					accept: '*'
				},
			}
		},
		inject: ["handleFileSuccess","closeFileDialog"],
		watch: {},
		computed: {},

		methods: {
			cancel(){
				//关闭
				this.closeFileDialog()
			},
			// 文件发生变化触发
			changeimg(file, fileList) {
				// this.tableDataES = fileList
				this.upload.fileList = fileList
			},
			// 点击上传
			submitUpload() {
				this.$refs.upload.submit();
			},
			// 点击移除
			deleteDocument(data) {
				// this.tableDataES.splice(data.$index, 1)
				this.upload.fileList.splice(data.$index, 1)
			},
			//进度条格式化
			percentageFormat(value) {
				if (value != 0) {
					value = Math.floor(value * 100) / 100
				}
				return value + '%'
			},
			// 点击文件列表中已上传的文件时的钩子
			handlePreview(file) {
				console.log('上传成功返回的数据', file.response.msg);
			},
			// 文件列表移除文件时的钩子
			handleRemove(file, fileList) {
				console.log(file, fileList);
			},
			// 文件上传时的钩子
			handleProgress(event, file, fileList) {},
			// 文件上传成功时的钩子
			handleAvatarSuccess(response, file, fileList) {
				this.uploadCount++;
				if (this.uploadCount == this.upload.fileList.length) {
					setTimeout(() => {
						this.$message({
							message: '共' + this.uploadCount + '个文件上传成功',
							type: 'success'
						})
					}, 1000)
				}
				this.handleFileSuccess(response, file, fileList)
			},
			// 删除文件之前的钩子,参数为上传的文件和文件列表
			beforeRemove(file, fileList) {
				return this.$confirm(`确定移除 ${file.name}`);
			},
			//  文件上传失败显示一个提示
			handleVideoError() {
				this.$message.error('上传失败!')
			},
		},
	}
</script>

<style scoped>
	.box_upload {
		display: flex;
		justify-content: flex-end;
	}

	.tablebox {
		margin-bottom: 15px;
		height: 300px;
		border: 1px solid #DCDCDC;
	}
</style>

3、调用组件举例

(非完整代码,注意组件调用位置和相关参数、方法传递)

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="标题" prop="title">
        <el-input
          v-model="queryParams.title"
          placeholder="请输入标题"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
        >删除</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="internalMailSendList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="ID" align="center" prop="id" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="文件" prop="filePaths">
          <el-button  type="primary" @click="handleUpFileOpen">上传文件</el-button>
        </el-form-item> 
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 文件上传 -->
	<el-dialog title="文件上传" v-if="upFileOpen" :visible.sync="upFileOpen" width="500px" append-to-body>
	   <uploadFile :upload="upload"></uploadFile>
    </el-dialog>
	
  </div>
</template>

<script>
import uploadFile from "@/components/UploadFile/index"
import { getToken } from "@/utils/auth";
export default {
  name: "InternalMailSend",
  components: {
  	uploadFile
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 表格数据
      internalMailSendList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
	  upFileOpen:false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
      },
	  // 上传参数
	  upload: {
	  	// 是否禁用上传
	  	isUploading: false,
	  	// 设置上传的请求头部
	  	headers: {
	  		Authorization: "Bearer " + getToken()
	  	},
	  	// 上传的地址
	  	url: process.env.VUE_APP_BASE_API + "/common/upload",
	  	// 上传的文件列表
	  	fileList: [],
	  	upFilePath: [],
	  },
    };
  },
  created() {
    this.getList();
  },
  provide() {
    return {
      handleFileSuccess: this.handleFileSuccess,
	  closeFileDialog:this.handleCloseFileDialog,
    };
  },
  methods: {
	//关闭文件上传
	handleCloseFileDialog(){
		this.upFileOpen=false
	},
	//打开文件上传
	handleUpFileOpen(){
		this.upFileOpen=true
	},
	/**文件上传成功*/
	handleFileSuccess(response, file, fileList) {
	  this.upload.isUploading = false;
	  let obj={
		  name:response.originalFilename,
		  url:response.fileName,
		  //后台返回文件大小kb
		  size:response.size,
		  percentage:100
	  }
	  this.upload.upFilePath.push(obj);
	},
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "xxxxxxxxx";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
	  this.upload.fileList=[]
      const id = row.id || this.ids
      getInternalMailSend(id).then(response => {
        this.form = response.data;
		if (this.form.filePaths) {
		  this.upload.fileList = JSON.parse(this.form.filePaths)
		  this.upload.upFilePath = JSON.parse(this.form.filePaths)
		}
        this.open = true;
        this.title = "xxxxxxxxxxxxxxxx";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
		  if (this.upload.upFilePath != null) {
		    this.form.filePaths =JSON.stringify(this.upload.upFilePath) 
		  }
        if (valid) {
          if (this.form.id != null) {
            updateInternalMailSend(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addInternalMailSend(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
  }
};
</script>
;