作者 若依
提交者 Gitee

!429 修复自定义组件`file-upload`无法显示第一个文件,列表显示的文件比实际文件少一个的问题

Merge pull request !429 from hjk2008/master
1 -<template>  
2 - <div class="upload-file">  
3 - <el-upload  
4 - :action="uploadFileUrl"  
5 - :before-upload="handleBeforeUpload"  
6 - :file-list="fileList"  
7 - :limit="limit"  
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 fileList">  
30 - <el-link :href="`${baseUrl}${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 - name: "FileUpload",  
46 - props: {  
47 - // 值  
48 - value: [String, Object, Array],  
49 - // 数量限制  
50 - limit: {  
51 - type: Number,  
52 - default: 5,  
53 - },  
54 - // 大小限制(MB)  
55 - fileSize: {  
56 - type: Number,  
57 - default: 5,  
58 - },  
59 - // 文件类型, 例如['png', 'jpg', 'jpeg']  
60 - fileType: {  
61 - type: Array,  
62 - default: () => ["doc", "xls", "ppt", "txt", "pdf"],  
63 - },  
64 - // 是否显示提示  
65 - isShowTip: {  
66 - type: Boolean,  
67 - default: true  
68 - }  
69 - },  
70 - data() {  
71 - return {  
72 - baseUrl: process.env.VUE_APP_BASE_API,  
73 - uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址  
74 - headers: {  
75 - Authorization: "Bearer " + getToken(),  
76 - },  
77 - fileList: [],  
78 - };  
79 - },  
80 - watch: {  
81 - value: {  
82 - handler(val) {  
83 - if (val) {  
84 - let temp = 1;  
85 - // 首先将值转为数组  
86 - const list = Array.isArray(val) ? val : this.value.split(',');  
87 - // 然后将数组转为对象数组  
88 - this.fileList = list.map(item => {  
89 - if (typeof item === "string") {  
90 - item = { name: item, url: item };  
91 - }  
92 - item.uid = item.uid || new Date().getTime() + temp++;  
93 - return item;  
94 - });  
95 - } else {  
96 - this.fileList = [];  
97 - return [];  
98 - }  
99 - },  
100 - deep: true,  
101 - immediate: true  
102 - }  
103 - },  
104 - computed: {  
105 - // 是否显示提示  
106 - showTip() {  
107 - return this.isShowTip && (this.fileType || this.fileSize);  
108 - },  
109 - },  
110 - methods: {  
111 - // 上传前校检格式和大小  
112 - handleBeforeUpload(file) {  
113 - // 校检文件类型  
114 - if (this.fileType) {  
115 - let fileExtension = "";  
116 - if (file.name.lastIndexOf(".") > -1) {  
117 - fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);  
118 - }  
119 - const isTypeOk = this.fileType.some((type) => {  
120 - if (file.type.indexOf(type) > -1) return true;  
121 - if (fileExtension && fileExtension.indexOf(type) > -1) return true;  
122 - return false;  
123 - });  
124 - if (!isTypeOk) {  
125 - this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);  
126 - return false;  
127 - }  
128 - }  
129 - // 校检文件大小  
130 - if (this.fileSize) {  
131 - const isLt = file.size / 1024 / 1024 < this.fileSize;  
132 - if (!isLt) {  
133 - this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);  
134 - return false;  
135 - }  
136 - }  
137 - return true;  
138 - },  
139 - // 文件个数超出  
140 - handleExceed() {  
141 - this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);  
142 - },  
143 - // 上传失败  
144 - handleUploadError(err) {  
145 - this.$message.error("上传失败, 请重试");  
146 - },  
147 - // 上传成功回调  
148 - handleUploadSuccess(res, file) {  
149 - this.$message.success("上传成功");  
150 - this.fileList.push({ name: res.fileName, url: res.fileName });  
151 - this.$emit("input", this.listToString(this.fileList));  
152 - },  
153 - // 删除文件  
154 - handleDelete(index) {  
155 - this.fileList.splice(index, 1);  
156 - this.$emit("input", this.listToString(this.fileList));  
157 - },  
158 - // 获取文件名称  
159 - getFileName(name) {  
160 - if (name.lastIndexOf("/") > -1) {  
161 - return name.slice(name.lastIndexOf("/") + 1).toLowerCase();  
162 - } else {  
163 - return "";  
164 - }  
165 - },  
166 - // 对象转成指定字符串分隔  
167 - listToString(list, separator) {  
168 - let strs = "";  
169 - separator = separator || ",";  
170 - for (let i in list) {  
171 - strs += list[i].url + separator;  
172 - }  
173 - return strs != '' ? strs.substr(0, strs.length - 1) : '';  
174 - }  
175 - }  
176 -};  
177 -</script>  
178 -  
179 -<style scoped lang="scss">  
180 -.upload-file-uploader {  
181 - margin-bottom: 5px;  
182 -}  
183 -.upload-file-list .el-upload-list__item {  
184 - border: 1px solid #e4e7ed;  
185 - line-height: 2;  
186 - margin-bottom: 10px;  
187 - position: relative;  
188 -}  
189 -.upload-file-list .ele-upload-list__item-content {  
190 - display: flex;  
191 - justify-content: space-between;  
192 - align-items: center;  
193 - color: inherit;  
194 -}  
195 -.ele-upload-list__item-content-action .el-link {  
196 - margin-right: 10px;  
197 -}  
198 -</style>  
  1 +<template>
  2 + <div class="upload-file">
  3 + <el-upload
  4 + :action="uploadFileUrl"
  5 + :before-upload="handleBeforeUpload"
  6 + :file-list="fileList"
  7 + :limit="limit"
  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.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
  30 + <el-link :href="`${baseUrl}${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 + name: "FileUpload",
  46 + props: {
  47 + // 值
  48 + value: [String, Object, Array],
  49 + // 数量限制
  50 + limit: {
  51 + type: Number,
  52 + default: 5,
  53 + },
  54 + // 大小限制(MB)
  55 + fileSize: {
  56 + type: Number,
  57 + default: 5,
  58 + },
  59 + // 文件类型, 例如['png', 'jpg', 'jpeg']
  60 + fileType: {
  61 + type: Array,
  62 + default: () => ["doc", "xls", "ppt", "txt", "pdf"],
  63 + },
  64 + // 是否显示提示
  65 + isShowTip: {
  66 + type: Boolean,
  67 + default: true
  68 + }
  69 + },
  70 + data() {
  71 + return {
  72 + baseUrl: process.env.VUE_APP_BASE_API,
  73 + uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
  74 + headers: {
  75 + Authorization: "Bearer " + getToken(),
  76 + },
  77 + fileList: [],
  78 + };
  79 + },
  80 + watch: {
  81 + value: {
  82 + handler(val) {
  83 + if (val) {
  84 + let temp = 1;
  85 + // 首先将值转为数组
  86 + const list = Array.isArray(val) ? val : this.value.split(',');
  87 + // 然后将数组转为对象数组
  88 + this.fileList = list.map(item => {
  89 + if (typeof item === "string") {
  90 + item = { name: item, url: item };
  91 + }
  92 + item.uid = item.uid || new Date().getTime() + temp++;
  93 + return item;
  94 + });
  95 + } else {
  96 + this.fileList = [];
  97 + return [];
  98 + }
  99 + },
  100 + deep: true,
  101 + immediate: true
  102 + }
  103 + },
  104 + computed: {
  105 + // 是否显示提示
  106 + showTip() {
  107 + return this.isShowTip && (this.fileType || this.fileSize);
  108 + },
  109 + },
  110 + methods: {
  111 + // 上传前校检格式和大小
  112 + handleBeforeUpload(file) {
  113 + // 校检文件类型
  114 + if (this.fileType) {
  115 + let fileExtension = "";
  116 + if (file.name.lastIndexOf(".") > -1) {
  117 + fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
  118 + }
  119 + const isTypeOk = this.fileType.some((type) => {
  120 + if (file.type.indexOf(type) > -1) return true;
  121 + if (fileExtension && fileExtension.indexOf(type) > -1) return true;
  122 + return false;
  123 + });
  124 + if (!isTypeOk) {
  125 + this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
  126 + return false;
  127 + }
  128 + }
  129 + // 校检文件大小
  130 + if (this.fileSize) {
  131 + const isLt = file.size / 1024 / 1024 < this.fileSize;
  132 + if (!isLt) {
  133 + this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
  134 + return false;
  135 + }
  136 + }
  137 + return true;
  138 + },
  139 + // 文件个数超出
  140 + handleExceed() {
  141 + this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
  142 + },
  143 + // 上传失败
  144 + handleUploadError(err) {
  145 + this.$message.error("上传失败, 请重试");
  146 + },
  147 + // 上传成功回调
  148 + handleUploadSuccess(res, file) {
  149 + this.$message.success("上传成功");
  150 + this.fileList.push({ name: res.fileName, url: res.fileName });
  151 + this.$emit("input", this.listToString(this.fileList));
  152 + },
  153 + // 删除文件
  154 + handleDelete(index) {
  155 + this.fileList.splice(index, 1);
  156 + this.$emit("input", this.listToString(this.fileList));
  157 + },
  158 + // 获取文件名称
  159 + getFileName(name) {
  160 + if (name.lastIndexOf("/") > -1) {
  161 + return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
  162 + } else {
  163 + return "";
  164 + }
  165 + },
  166 + // 对象转成指定字符串分隔
  167 + listToString(list, separator) {
  168 + let strs = "";
  169 + separator = separator || ",";
  170 + for (let i in list) {
  171 + strs += list[i].url + separator;
  172 + }
  173 + return strs != '' ? strs.substr(0, strs.length - 1) : '';
  174 + }
  175 + }
  176 +};
  177 +</script>
  178 +
  179 +<style scoped lang="scss">
  180 +.upload-file-uploader {
  181 + margin-bottom: 5px;
  182 +}
  183 +.upload-file-list .el-upload-list__item {
  184 + border: 1px solid #e4e7ed;
  185 + line-height: 2;
  186 + margin-bottom: 10px;
  187 + position: relative;
  188 +}
  189 +.upload-file-list .ele-upload-list__item-content {
  190 + display: flex;
  191 + justify-content: space-between;
  192 + align-items: center;
  193 + color: inherit;
  194 +}
  195 +.ele-upload-list__item-content-action .el-link {
  196 + margin-right: 10px;
  197 +}
  198 +</style>