关于vue项目中文件上传,复现,模版下载常见用法(el-upload)
最新在做一个页面,涉及到文件上传及文件回显,界面如下:
直接上文件代码,这里算是较为全面的文件上传了
1 <template> 2 <div class="information-wrapper"> 3 <div class="content"> 4 <el-form 5 ref="informationForm" 6 :model="ruleForm" 7 :rules="rules" 8 :inline="true" 9 class="information-form" 10 label-width="110px" 11 size="mini" 12 > 13 <div class="base-info"> 14 <div class="title">基本信息</div> 15 </div> 16 <div class="base-content"> 17 <el-row :gutter="20"> 18 <el-col :span="6"> 19 <el-form-item label="发起机制" prop="machine"> 20 <el-input 21 :disabled="true" 22 v-model="ruleForm.machine" 23 placeholder="请填写发起机制" 24 ></el-input> 25 </el-form-item> 26 </el-col> 27 <el-col :span="6"> 28 <el-form-item label="需求发起方" prop="initiator"> 29 <el-input 30 :disabled="true" 31 v-model="ruleForm.initiator" 32 placeholder="请填写需求发起方" 33 ></el-input> 34 </el-form-item> 35 </el-col> 36 <el-col :span="6"> 37 <el-form-item label="需求名称" prop="name"> 38 <el-input 39 :disabled="disableForm" 40 :clearable="true" 41 v-model="ruleForm.name" 42 placeholder="请填写需求名称" 43 ></el-input> 44 </el-form-item> 45 </el-col> 46 <el-col :span="6"> 47 <el-form-item label="需求类别" prop="type"> 48 <el-select 49 :disabled="disableForm" 50 v-model="ruleForm.type" 51 placeholder="请选择需求类别" 52 > 53 <el-option 54 v-for="type in typeList" 55 :key="type.id" 56 :label="type.name" 57 :value="type.id" 58 >{{ type.name }} 59 </el-option> 60 </el-select> 61 </el-form-item> 62 </el-col> 63 </el-row> 64 <el-row :gutter="20"> 65 <el-col :span="6"> 66 <el-form-item label="需求业务领域" prop="appArea"> 67 <el-select 68 :disabled="disableForm" 69 v-model="ruleForm.appArea" 70 placeholder="请选择需求业务领域" 71 > 72 <el-option 73 v-for="type in businessList" 74 :key="type.id" 75 :label="type.name" 76 :value="type.id" 77 ></el-option> 78 </el-select> 79 </el-form-item> 80 </el-col> 81 <el-col :span="6"> 82 <el-form-item label="需求周期" prop="period"> 83 <el-input 84 :disabled="disableForm" 85 :clearable="true" 86 v-model="ruleForm.period" 87 placeholder="请填写需求周期" 88 ></el-input> 89 </el-form-item> 90 </el-col> 91 <el-col :span="6"> 92 <el-form-item label="交付时间" prop="deliveryTime"> 93 <el-date-picker 94 :disabled="disableForm" 95 v-model="ruleForm.deliveryTime" 96 type="datetime" 97 value-format="yyyy-MM-dd HH:mm:ss" 98 placeholder="选择日期" 99 > 100 </el-date-picker> 101 </el-form-item> 102 </el-col> 103 </el-row> 104 <el-row :gutter="10"> 105 <el-col :span="12"> 106 <el-form-item 107 class="demand-desc" 108 label="需求描述" 109 prop="demandDesc" 110 > 111 <el-input 112 type="textarea" 113 class="demand-desc" 114 :disabled="disableForm" 115 :clearable="true" 116 :rows="5" 117 resize="none" 118 v-model="ruleForm.demandDesc" 119 placeholder="请填写需求描述" 120 ></el-input> 121 </el-form-item> 122 </el-col> 123 </el-row> 124 </div> 125 <div class="source-info"> 126 <div class="title">资源要素</div> 127 </div> 128 <el-row :gutter="20"> 129 <el-col :span="24"> 130 <el-form-item label="示范场站" prop="factorsSub"> 131 <el-input 132 :disabled="disableForm" 133 :clearable="true" 134 v-model="ruleForm.factorsSub" 135 placeholder="请填写示范场站" 136 ></el-input> 137 </el-form-item> 138 </el-col> 139 </el-row> 140 <el-row :gutter="20"> 141 <el-col :span="24"> 142 <el-form-item 143 v-if="!disableForm" 144 class="upload-down-btn" 145 label="基础数据" 146 prop="factorsData" 147 > 148 <el-upload 149 ref="factorsData" 150 :file-list="ruleForm.factorsData" 151 multiple 152 :action="importFileUrl" 153 :on-success="fileSuccess.bind(this, 'factorsData')" 154 :on-error="handleError" 155 :on-remove="fileRemove.bind(this, 'factorsData')" 156 > 157 <el-button size="mini" round type="primary">点击上传</el-button> 158 <!-- <div slot="tip" class="el-upload__tip">只能上传excel文件</div> --> 159 </el-upload> 160 <el-button 161 @click="downloadTemplateFile('demandFactorsData.xlsx')" 162 class="down-btn" 163 size="mini" 164 round 165 type="info" 166 >模版下载</el-button 167 > 168 </el-form-item> 169 <el-form-item v-else label="基础数据"> 170 <div 171 v-for="item in ruleForm.factorsData" 172 :key="item.url" 173 :gutter="10" 174 class="down-file-list" 175 > 176 <el-button 177 size="mini" 178 round 179 type="primary" 180 @click="downloadFile(item.url)" 181 >下载</el-button 182 > 183 <span class="down-file-name">{{ item.name }}</span> 184 </div> 185 </el-form-item> 186 </el-col> 187 </el-row> 188 <el-row :gutter="20"> 189 <el-col :span="24"> 190 <el-form-item 191 v-if="!disableForm" 192 class="upload-down-btn" 193 label="部署资源" 194 prop="factorsParts" 195 > 196 <el-upload 197 ref="factorsParts" 198 :file-list="ruleForm.factorsParts" 199 multiple 200 :action="importFileUrl" 201 :on-success="fileSuccess.bind(this, 'factorsParts')" 202 :on-error="handleError" 203 :on-remove="fileRemove.bind(this, 'factorsParts')" 204 > 205 <el-button size="mini" round type="primary">点击上传</el-button> 206 <!-- <div slot="tip" class="el-upload__tip">只能上传excel文件</div> --> 207 </el-upload> 208 <el-button 209 @click="downloadTemplateFile('demandFactorsParts.xlsx')" 210 class="down-btn" 211 size="mini" 212 round 213 type="info" 214 >模版下载</el-button 215 > 216 </el-form-item> 217 <el-form-item v-else label="部署资源"> 218 <div 219 v-for="item in ruleForm.factorsParts" 220 :key="item.url" 221 :gutter="10" 222 class="down-file-list" 223 > 224 <el-button 225 size="mini" 226 round 227 type="primary" 228 @click="downloadFile(item.url)" 229 >下载</el-button 230 > 231 <span class="down-file-name">{{ item.name }}</span> 232 </div> 233 </el-form-item> 234 </el-col> 235 </el-row> 236 <div class="source-info"> 237 <div class="title">需求资料</div> 238 </div> 239 <el-row :gutter="20"> 240 <el-col :span="24"> 241 <el-form-item 242 v-if="!disableForm" 243 class="upload-down-btn" 244 label="需求说明书" 245 prop="specificationFile" 246 > 247 <el-upload 248 ref="specificationFile" 249 :file-list="ruleForm.specificationFile" 250 multiple 251 :action="importFileUrl" 252 :on-success="fileSuccess.bind(this, 'specificationFile')" 253 :on-error="handleError" 254 :on-remove="fileRemove.bind(this, 'specificationFile')" 255 > 256 <el-button size="mini" round type="primary">点击上传</el-button> 257 </el-upload> 258 <el-button 259 @click="downloadTemplateFile('demandSpecificationFile.docx')" 260 class="down-btn" 261 size="mini" 262 round 263 type="info" 264 >模版下载</el-button 265 > 266 </el-form-item> 267 <el-form-item v-else label="需求说明书"> 268 <div 269 v-for="item in ruleForm.specificationFile" 270 :key="item.url" 271 :gutter="10" 272 class="down-file-list" 273 > 274 <el-button 275 size="mini" 276 round 277 type="primary" 278 @click="downloadFile(item.url)" 279 >下载</el-button 280 > 281 <span class="down-file-name">{{ item.name }}</span> 282 </div> 283 </el-form-item> 284 </el-col> 285 </el-row> 286 <el-row :gutter="20"> 287 <el-col :span="24"> 288 <el-form-item 289 v-if="!disableForm" 290 class="upload-down-btn" 291 label="其他说明文件" 292 prop="otherFile" 293 > 294 <el-upload 295 ref="otherFile" 296 :file-list="ruleForm.otherFile" 297 multiple 298 :action="importFileUrl" 299 :on-success="fileSuccess.bind(this, 'otherFile')" 300 :on-error="handleError" 301 :on-remove="fileRemove.bind(this, 'otherFile')" 302 > 303 <el-button size="mini" round type="primary">点击上传</el-button> 304 </el-upload> 305 <el-button 306 @click="downloadTemplateFile('demandOtherFile.docx')" 307 class="down-btn" 308 size="mini" 309 round 310 type="info" 311 >模版下载</el-button 312 > 313 </el-form-item> 314 <el-form-item v-else label="其他说明文件"> 315 <div 316 v-for="item in ruleForm.otherFile" 317 :key="item.url" 318 :gutter="10" 319 class="down-file-list" 320 > 321 <el-button 322 size="mini" 323 round 324 type="primary" 325 @click="downloadFile(item.url)" 326 >下载</el-button 327 > 328 <span class="down-file-name">{{ item.name }}</span> 329 </div> 330 </el-form-item> 331 </el-col> 332 </el-row> 333 </el-form> 334 </div> 335 <div class="footer" v-if="!disableForm"> 336 <el-button type="primary" size="mini" round @click="changeSteps" 337 >上一步</el-button 338 > 339 <!-- <el-button 340 type="primary" 341 size="mini" 342 round 343 @click="saveSubmitFile(0)" 344 >保存</el-button 345 > --> 346 <el-button type="primary" size="mini" round @click="saveSubmitFile(1)" 347 >提交</el-button 348 > 349 </div> 350 </div> 351 </template> 352 353 <script> 354 import { 355 addCommDemandMessage, 356 getCommDemandMessageByCode, 357 } from "@/api/community/commDemandMessage"; 358 import { getDicts } from "@/api/system/dict/data"; 359 export default { 360 name: "DemandInformation", 361 props: { 362 machine: { 363 type: String, 364 default: "", 365 }, 366 }, 367 data() { 368 return { 369 disableForm: this.$route.query.auditStatus === "1", 370 typeList: [], 371 businessList: [], 372 importFileUrl: `${process.env.VUE_APP_PROTAL_API}/community/commupload/upload`, 373 ruleForm: { 374 auditStatus: 0, 375 machine: this.machine, 376 initiator: sessionStorage.getItem("firmName"), 377 createBy: sessionStorage.getItem("username"), 378 name: "", 379 type: "", 380 appArea: "", 381 demandDesc: "", 382 period: "", 383 deliveryTime: "", 384 factorsSub: "", 385 factorsData: [], 386 factorsParts: [], 387 specificationFile: [], 388 otherFile: [], 389 }, 390 rules: { 391 machine: [ 392 { required: true, message: "请填写发起机制", trigger: "blur" }, 393 ], 394 initiator: [ 395 { required: true, message: "请填写需求发起方", trigger: "blur" }, 396 ], 397 name: [{ required: true, message: "请填写需求名称", trigger: "blur" }], 398 type: [ 399 { required: true, message: "请选择需求类别", trigger: "change" }, 400 ], 401 appArea: [ 402 { required: true, message: "请选择需求业务领域", trigger: "change" }, 403 ], 404 demandDesc: [ 405 { required: true, message: "请填写需求描述", trigger: "blur" }, 406 ], 407 period: [ 408 { required: true, message: "请填写需求周期", trigger: "blur" }, 409 ], 410 deliveryTime: [ 411 { required: true, message: "请填写交付时间", trigger: "blur" }, 412 ], 413 factorsSub: [ 414 { required: true, message: "请填写示范场站", trigger: "blur" }, 415 ], 416 }, 417 }; 418 }, 419 mounted() { 420 this.getTypeList(); 421 this.getBusinessList(); 422 if (this.$route.query.auditStatus) { 423 this.getByCode(); 424 } 425 }, 426 methods: { 427 // 根据编码获取需求信息 428 getByCode() { 429 const code = this.$route.query.demandCode; 430 getCommDemandMessageByCode({ code }).then((res) => { 431 const ruleFormData = JSON.parse(JSON.stringify(res.data)); 432 ruleFormData.factorsData = this.formatFileData(res.data.factorsData); 433 ruleFormData.factorsParts = this.formatFileData(res.data.factorsParts); 434 ruleFormData.specificationFile = this.formatFileData( 435 res.data.specificationFile 436 ); 437 ruleFormData.otherFile = this.formatFileData(res.data.otherFile); 438 this.ruleForm = ruleFormData; 439 this.$route.query.auditStatus == 1 && (this.disableForm = true); 440 }); 441 }, 442 443 // 文件上传成功 444 fileSuccess(uploadBtn, res, file, fileList) { 445 fileList.forEach((item, index) => { 446 if (item.response) { 447 this.ruleForm[uploadBtn][index] = { 448 name: item.response.name, 449 url: item.response.url, 450 }; 451 } 452 }); 453 }, 454 455 // 文件删除 456 fileRemove(uploadBtn, file, fileList) { 457 this.ruleForm[uploadBtn] = []; 458 fileList.forEach((item, index) => { 459 this.ruleForm[uploadBtn][index] = { 460 name: item.response.name, 461 url: item.response.url, 462 }; 463 }); 464 }, 465 466 // 文件提交错误 467 handleError() { 468 this.$message({ 469 message: "上传失败,请重新操作!", 470 type: "error", 471 }); 472 }, 473 474 // 保存提交操作 475 saveSubmitFile(num) { 476 this.$refs.informationForm.validate((valid) => { 477 if (valid) { 478 const ruleForm = JSON.parse(JSON.stringify(this.ruleForm)); 479 ruleForm.auditStatus = num; 480 ruleForm.factorsData = JSON.stringify(this.ruleForm.factorsData); 481 ruleForm.factorsParts = JSON.stringify(this.ruleForm.factorsParts); 482 ruleForm.specificationFile = JSON.stringify( 483 this.ruleForm.specificationFile 484 ); 485 ruleForm.otherFile = JSON.stringify(this.ruleForm.otherFile); 486 addCommDemandMessage(ruleForm).then((res) => { 487 if (res.code === 200) { 488 if (num === 1) { 489 this.$alert( 490 "你的申请已经提交,请等待审核,审核进度请前往需求列表查看", 491 "提示消息", 492 { 493 confirmButtonText: "确定", 494 callback: (action) => { 495 this.$router.push({ 496 path: "/demand/list", 497 }); 498 }, 499 } 500 ); 501 this.disableForm = true; 502 this.resetForm(); 503 } else { 504 } 505 } else { 506 this.msgError(res.msg); 507 } 508 }); 509 } else { 510 return false; 511 } 512 }); 513 }, 514 515 // 重置表单 516 resetForm() { 517 this.$refs.informationForm.resetFields(); 518 this.$refs.factorsData.clearFiles(); 519 this.$refs.factorsParts.clearFiles(); 520 this.$refs.specificationFile.clearFiles(); 521 this.$refs.otherFile.clearFiles(); 522 }, 523 524 // 处理文件保存数据格式 525 formatFileData(data) { 526 if (data === "" || !Array.isArray(JSON.parse(data))) { 527 return []; 528 } 529 return JSON.parse(data); 530 }, 531 532 // 获取类别列表 533 getTypeList() { 534 getDicts("comm_type").then((res) => { 535 res.data.forEach((item, index) => { 536 this.typeList.push({ 537 id: item.dictValue, 538 name: item.dictLabel, 539 }); 540 }); 541 }); 542 }, 543 544 // 获取需求业务领域列表 545 getBusinessList() { 546 getDicts("comm_app_area").then((res) => { 547 res.data.forEach((item, index) => { 548 this.businessList.push({ 549 id: item.dictValue, 550 name: item.dictLabel, 551 }); 552 }); 553 }); 554 }, 555 556 // 上一步 557 changeSteps() { 558 this.$emit("changeSteps", 0); 559 }, 560 561 // 模板文件下载 562 downloadTemplateFile(fileName) { 563 window.open("/templateFile/" + fileName); 564 }, 565 566 downloadFile(url) { 567 let downloadUrl = 568 process.env.NODE_ENV === "production" ? "/prod-api" : "/dev-api"; 569 if (url) { 570 window.open(downloadUrl + "/community/commupload/download?name=" + url); 571 } else { 572 this.$message({ 573 message: "暂无文件下载", 574 type: "error", 575 }); 576 } 577 }, 578 }, 579 }; 580 </script> 581 582 <style lang="scss" scoped> 583 @import "./demand.scss"; 584 .information-wrapper { 585 .content { 586 .information-form .base-content { 587 /deep/ .el-form-item { 588 width: auto; 589 } 590 /deep/ .el-form-item__content { 591 width: 200px; 592 .el-select { 593 width: 200px; 594 } 595 } 596 } 597 } 598 } 599 600 .upload-down-btn { 601 position: relative; 602 .down-btn { 603 position: absolute; 604 top: 0; 605 left: 100px; 606 } 607 } 608 609 .demand-desc { 610 width: 100% !important; 611 } 612 613 .demand-desc >>> .el-form-item__content { 614 width: 80% !important; 615 } 616 617 .down-file-list { 618 margin-bottom: 10px; 619 } 620 621 .down-file-name { 622 margin-left: 10px; 623 } 624 </style>