作者 RuoYi

新增文件上传组件

  1 +<template>
  2 + <div class="upload-file">
  3 + <el-upload
  4 + :action="uploadFileUrl"
  5 + :before-upload="handleBeforeUpload"
  6 + :file-list="fileList"
  7 + :limit="1"
  8 + :on-error="handleUploadError"
  9 + :on-exceed="handleExceed"
  10 + :on-success="handleUploadSuccess"
  11 + :show-file-list="false"
  12 + :headers="headers"
  13 + class="upload-file-uploader"
  14 + ref="upload"
  15 + >
  16 + <!-- 上传按钮 -->
  17 + <el-button size="mini" type="primary">选取文件</el-button>
  18 + <!-- 上传提示 -->
  19 + <div class="el-upload__tip" slot="tip" v-if="showTip">
  20 + 请上传
  21 + <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
  22 + <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
  23 + 的文件
  24 + </div>
  25 + </el-upload>
  26 +
  27 + <!-- 文件列表 -->
  28 + <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
  29 + <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in list">
  30 + <el-link :href="file.url" :underline="false" target="_blank">
  31 + <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
  32 + </el-link>
  33 + <div class="ele-upload-list__item-content-action">
  34 + <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
  35 + </div>
  36 + </li>
  37 + </transition-group>
  38 + </div>
  39 +</template>
  40 +
  41 +<script>
  42 +import { getToken } from "@/utils/auth";
  43 +
  44 +export default {
  45 + props: {
  46 + // 值
  47 + value: [String, Object, Array],
  48 + // 大小限制(MB)
  49 + fileSize: {
  50 + type: Number,
  51 + default: 5,
  52 + },
  53 + // 文件类型, 例如['png', 'jpg', 'jpeg']
  54 + fileType: {
  55 + type: Array,
  56 + default: () => ["doc", "xls", "ppt", "txt", "pdf"],
  57 + },
  58 + // 是否显示提示
  59 + isShowTip: {
  60 + type: Boolean,
  61 + default: true
  62 + }
  63 + },
  64 + data() {
  65 + return {
  66 + uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
  67 + headers: {
  68 + Authorization: "Bearer " + getToken(),
  69 + },
  70 + fileList: [],
  71 + };
  72 + },
  73 + computed: {
  74 + // 是否显示提示
  75 + showTip() {
  76 + return this.isShowTip && (this.fileType || this.fileSize);
  77 + },
  78 + // 列表
  79 + list() {
  80 + let temp = 1;
  81 + if (this.value) {
  82 + // 首先将值转为数组
  83 + const list = Array.isArray(this.value) ? this.value : [this.value];
  84 + // 然后将数组转为对象数组
  85 + return list.map((item) => {
  86 + if (typeof item === "string") {
  87 + item = { name: item, url: item };
  88 + }
  89 + item.uid = item.uid || new Date().getTime() + temp++;
  90 + return item;
  91 + });
  92 + } else {
  93 + return [];
  94 + }
  95 + },
  96 + },
  97 + methods: {
  98 + // 上传前校检格式和大小
  99 + handleBeforeUpload(file) {
  100 + // 校检文件类型
  101 + if (this.fileType) {
  102 + let fileExtension = "";
  103 + if (file.name.lastIndexOf(".") > -1) {
  104 + fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
  105 + }
  106 + const isTypeOk = this.fileType.some((type) => {
  107 + if (file.type.indexOf(type) > -1) return true;
  108 + if (fileExtension && fileExtension.indexOf(type) > -1) return true;
  109 + return false;
  110 + });
  111 + if (!isTypeOk) {
  112 + this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
  113 + return false;
  114 + }
  115 + }
  116 + // 校检文件大小
  117 + if (this.fileSize) {
  118 + const isLt = file.size / 1024 / 1024 < this.fileSize;
  119 + if (!isLt) {
  120 + this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
  121 + return false;
  122 + }
  123 + }
  124 + return true;
  125 + },
  126 + // 文件个数超出
  127 + handleExceed() {
  128 + this.$message.error(`只允许上传单个文件`);
  129 + },
  130 + // 上传失败
  131 + handleUploadError(err) {
  132 + this.$message.error("上传失败, 请重试");
  133 + },
  134 + // 上传成功回调
  135 + handleUploadSuccess(res, file) {
  136 + this.$message.success("上传成功");
  137 + this.$emit("input", res.url);
  138 + },
  139 + // 删除文件
  140 + handleDelete(index) {
  141 + this.fileList.splice(index, 1);
  142 + this.$emit("input", '');
  143 + },
  144 + // 获取文件名称
  145 + getFileName(name) {
  146 + if (name.lastIndexOf("/") > -1) {
  147 + return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
  148 + } else {
  149 + return "";
  150 + }
  151 + }
  152 + },
  153 + created() {
  154 + this.fileList = this.list;
  155 + },
  156 +};
  157 +</script>
  158 +
  159 +<style scoped lang="scss">
  160 +.upload-file-uploader {
  161 + margin-bottom: 5px;
  162 +}
  163 +.upload-file-list .el-upload-list__item {
  164 + border: 1px solid #e4e7ed;
  165 + line-height: 2;
  166 + margin-bottom: 10px;
  167 + position: relative;
  168 +}
  169 +.upload-file-list .ele-upload-list__item-content {
  170 + display: flex;
  171 + justify-content: space-between;
  172 + align-items: center;
  173 + color: inherit;
  174 +}
  175 +.ele-upload-list__item-content-action .el-link {
  176 + margin-right: 10px;
  177 +}
  178 +</style>
@@ -34,7 +34,6 @@ @@ -34,7 +34,6 @@
34 import { getToken } from "@/utils/auth"; 34 import { getToken } from "@/utils/auth";
35 35
36 export default { 36 export default {
37 - components: {},  
38 data() { 37 data() {
39 return { 38 return {
40 uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 39 uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址