在原生js的基础上进行的封装,多图和单图的关键在于input的multiple属性
<template> <div class="upload-wrap"> <input :id="upfileId" type="file" name="fileName" :multiple="multiple" :accept="accept" /> <img v-if="imageUrl" :src="imageUrl" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> <span v-if="imageUrl" class="el-upload__tip">{{uploadTip}}</span> </div> </template> <script> import api from "api"; export default { name: "com-upload", props: { upfileId: { // 组件id type: String, default: "upload" }, multiple: { // false默认单图上传,true多图上传 type: Boolean, default: false }, accept: { // 接收文件的类型 type: String, default: "image/*" }, size: { // 文件大小限制 type: String, default: "3M" }, uploadTip: { //上传文件类型文本提示 type: String, default: "jpg/jpeg/gif/png" }, type: { //来源 type: String, default: "logo" }, fileType: { type: String, default: "" }, imageUrl: { //默认样式图片 type: String, default: "logo" }, cb: { // 上传回调 type: Function, default: function() {} } }, data() { return { uploading: false, formValidations: true }; }, computed: { fileSize() { let tempSize = ""; let mt = this.size.match(/^([\d\.]+)([^\d\.]*)$/i); if (!!mt) { let bit = mt[2].toLowerCase(); if (bit === "m" || bit === "mb") { tempSize = mt[1] * 1024 * 1024; } else if (bit === "kb" || bit === "k" || bit === "KB") { tempSize = mt[1] * 1024; } } return tempSize; } }, mounted() { this.initUpload(); }, methods: { initUpload() { let _this = this; $("#" + _this.upfileId) .unbind("change") .bind("change", function() { var $this = $(this); var This = this; var len = This.files.length; _this.formValidations = true; _this.uploading = false; if (!!_this.numMax && len > _this.numMax) { _this.$message.error("单次上传不能超过" + _this.numMax + "个文件!"); $this.val(""); return false; } for (var i = 0; i < len; i++) { if (!!_this.size && This.files.item(i).size > _this.fileSize) { _this.formValidations = false; _this.$message.error("文件大小不能超过" + _this.size + "!"); $this.val(""); return false; } //判断文件类型是否合格 if ( !!_this.fileType && !eval(_this.fileType).test(This.files.item(i).name) ) { _this.formValidations = false; _this.$message.error("文件类型不正确!"); $this.val(""); return false; } } if (_this.uploading || !_this.formValidations) { _this.formValidations = true; return false; } let formData = new FormData($this.parents(".form_upload")[0]); _this.uploading = true; api.request("uploadFiles", formData, result => { // 存储图片的接口 if (result.status == 0) { let obj = {}; let morefile = []; for (let j = 0; j < result.data.length; j++) { morefile.push(result.data[j].file); } obj[_this.type] = morefile; obj["upfileId"] = _this.upfileId; !!_this.cb && _this.cb(obj); } else { _this.$message.error("图片上传失败!"); } $this.val(""); _this.uploading = false; }); }); } } }; </script> <style scoped> .upload-wrap { width: 122px; height: 122px; position: relative; border: 1px dotted #dfe5ec; border-radius: 5px; } .upload-wrap input { position: absolute; top: 0; left: 0; display: block; width: 100%; height: 100%; opacity: 0; filter: alpha(opacity=0); /* 兼容IE */ z-index: 9; } .upload-wrap .avatar-uploader-icon { position: absolute; top: 0px; left: 0px; font-size: 28px; color: #8c939d; width: 120px; height: 120px; line-height: 120px; text-align: center; z-index: 1; } .upload-wrap .avatar { position: absolute; top: 0px; left: 0px; width: 120px; height: 120px; display: block; z-index: 1; border-radius: 5px; } .upload-wrap .el-upload__tip { position: absolute; width: 100%; height: 40px; left: 0; bottom: 0; padding: 4px 15px 0; background-color: rgba(0, 0, 0, 0.3); color: #fff; z-index: 1; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } </style>
组件的运用
<form class="form_upload"> <comupload type="logo" size="5M" :upfileId="'upfileId' + index" uploadTip="jpg/jpeg/gif/png <3M" imageUrl="../../images/default.png" fileType="/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/" :multiple="true" :cb="uploadCompanyImgs" ></comupload> </form> // 上传图片后获得图片路径的回调方法 methods: { uploadCompanyImgs(data) { console.log('data', data) } }