| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 | <template>  <div class="component-upload-image">    <el-upload      v-if="type === 'more'"      multiple      action="#"      list-type="picture-card"      :on-success="handleUploadSuccess"      :before-upload="handleBeforeUpload"      :limit="limit"      :on-error="handleUploadError"      :on-exceed="handleExceed"      ref="imageUpload"      :on-remove="handleDelete"      :show-file-list="true"      :headers="headers"      :file-list="fileList"      :on-preview="handlePictureCardPreview"      :http-request="uploadImage"      :class="{ hide: fileList.length >= limit }"    >      <i class="el-icon-plus"></i>      <!-- 上传提示 -->      <div class="el-upload__tip" slot="tip" v-if="showTip">        请上传        <template v-if="fileSize">          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>        </template>        <template v-if="fileType">          格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>        </template>        的文件      </div>    </el-upload>    <el-upload      v-if="type === 'radioIcon'"      action="#"      list-type="picture-card"      :on-success="handleUploadSuccess"      :before-upload="handleBeforeUpload"      :limit="1"      :on-error="handleUploadError"      :on-exceed="handleExceed"      ref="imageUpload"      :on-remove="handleDelete"      :show-file-list="true"      :headers="headers"      :file-list="fileList"      :on-preview="handlePictureCardPreview"      :http-request="uploadImage"      :class="{ hide: fileList.length >0  }"    >      <i class="el-icon-plus"></i>            <!-- 上传提示 -->      <div  class="el-upload__tip" slot="tip" >        请上传        <template v-if="fileSize">          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>        </template>        <template v-if="fileType">          格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>        </template>        的文件      </div>    </el-upload>    <el-upload      v-if="type === 'alone'"      drag      action="#"      :before-upload="handleBeforeUpload"      :limit="2"      :on-error="handleUploadError"      ref="imageUpload"      :show-file-list="false"      :file-list="fileList"      :http-request="uploadImage"    >      <div v-if="fileList.length > 0" class="img-box">        <img style="width: 100%; height: 100%" :src="fileList[0].url" alt="" />        <div class="img-model" @click.stop="clickImg">          <span>预览</span>        </div>      </div>      <div v-else>        <i class="el-icon-upload"></i>        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>        <div class="el-upload__tip" slot="tip" v-if="showTip">          请上传          <template v-if="fileSize">            大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>          </template>          <template v-if="fileType">            格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>          </template>          的文件        </div>        <!--        <div class="el-upload__tip" slot="tip">只能上传jpg/png/jpeg文件,且不超过500kb</div>-->      </div>    </el-upload>    <el-dialog      :visible.sync="dialogVisible"      title="预览"      width="800"      append-to-body    >      <img        :src="dialogImageUrl"        style="display: block; max-width: 100%; margin: 0 auto"      />    </el-dialog>  </div></template><script>import { getToken } from "@/utils/auth";import { upload } from "@/api/system/public";export default {  props: {    value: [String, Object, Array],    //两种模式:more(多选)、alone(单选)    type: {      type: String,      default: "more",    },    // 图片数量限制(单选模式下失效)    limit: {      type: Number,      default: 5,    },    // 大小限制(MB)    fileSize: {      type: Number,      default: 5,    },    // 文件类型, 例如['png', 'jpg', 'jpeg']    fileType: {      type: Array,      default: () => ["png", "jpg", "jpeg"],    },    // 是否显示提示    isShowTip: {      type: Boolean,      default: true,    },  },  data() {    return {      number: 0,      uploadList: [],      dialogImageUrl: "",      dialogVisible: false,      hideUpload: false,      uploadImgUrl:        process.env.NODE_ENV === "development"          ? "/dev-api" + "/file/file/upload"          : process.env.VUE_APP_BASE_API + "/file/file/upload", // 上传的图片服务器地址      headers: {        Authorization: "Bearer " + getToken(),      },      fileList: [],      file: null,    };  },  watch: {    value: {      handler(val) {        if (val) {          // 首先将值转为数组          const list = Array.isArray(val) ? val : this.value.split(",");          // 然后将数组转为对象数组          this.fileList = list.map((item) => {            if (typeof item === "string") {              item = { name: item, url: item };            }            return item;          });        } else {          this.fileList = [];          return [];        }      },      deep: true,      immediate: true,    },  },  computed: {    // 是否显示提示    showTip() {      return this.isShowTip && (this.fileType || this.fileSize);    },  },  methods: {    //单传模式下的预览    clickImg() {      this.dialogImageUrl = this.fileList[0].url;      this.dialogVisible = true;    },    //自定义上传方式(自带的成功回调及失败回调会失效)    uploadImage(fileObj) {      console.log(window.origin, "URL");      let formData = new FormData();      formData.append("file", fileObj.file);      upload(formData, "image")        .then((res) => {          /*上传成功*/          this.$modal.closeLoading();          let imgUrl =            process.env.NODE_ENV === "development"              ? process.env.VUE_APP_BASE_API + res.data.url              : window.origin + res.data.url;          let arr = [];          arr.push({ name: res.data.name, url: imgUrl });          if(this.type=='more'){            this.fileList = this.fileList.concat(arr);          }          else{            this.fileList = arr;          }                    //emit完整图片URL路径          this.$emit("input", this.listToString(this.fileList));          // //非完整图片URL路径          // this.$emit("imgUrl", res.data.url);        })        .catch((err) => {          /*上传失败*/          this.$modal.closeLoading();          //this.$modal.msgError(res.msg);          this.$refs.imageUpload.handleRemove(fileObj.file);          //this.uploadedSuccessfully();        });    },    // 上传前loading加载    handleBeforeUpload(file) {      let isImg = false;      if (this.fileType.length) {        let fileExtension = "";        if (file.name.lastIndexOf(".") > -1) {          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);        }        isImg = this.fileType.some((type) => {          if (file.type.indexOf(type) > -1) return true;          if (fileExtension && fileExtension.indexOf(type) > -1) return true;          return false;        });      } else {        isImg = file.type.indexOf("image") > -1;      }      if (!isImg) {        this.$modal.msgError(          `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`        );        return false;      }      if (this.fileSize) {        const isLt = file.size / 1024 / 1024 < this.fileSize;        if (!isLt) {          this.$modal.msgError(`上传图片大小不能超过 ${this.fileSize} MB!`);          return false;        }      }      this.$modal.loading("正在上传图片,请稍候...");      this.number++;      this.file = file;    },    // 文件个数超出    handleExceed() {      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);    },    // 上传成功回调    handleUploadSuccess(res, file,fileList) {      console.log("handleUploadSuccess",res,file,fileList);      if (res.code === 200) {        let imgUrl = process.env.VUE_APP_BASE_API + res.data.url;        this.uploadList.push({ name: res.data.name, url: imgUrl });        this.uploadedSuccessfully();        // let str = res.data.code;        // let blob = new Blob([str],{type:'image/jpeg'});        // let imgUrl = window.URL.createObjectURL(blob);        // debugger      } else {        this.number--;        this.$modal.closeLoading();        this.$modal.msgError(res.msg);        this.$refs.imageUpload.handleRemove(file);        this.uploadedSuccessfully();      }    },    // 删除图片    handleDelete(file) {      const findex = this.fileList.map((f) => f.name).indexOf(file.name);      if (findex > -1) {        this.fileList.splice(findex, 1);        this.$emit("input", this.listToString(this.fileList));      }      console.log(this.listToString(this.fileList), "删除图片");    },    // 上传失败    handleUploadError() {      this.$modal.msgError("上传图片失败,请重试");      this.$modal.closeLoading();    },    // 上传结束处理    uploadedSuccessfully() {      if (this.number > 0 && this.uploadList.length === this.number) {        debugger        this.fileList = this.fileList.concat(this.uploadList);        this.uploadList = [];        this.number = 0;        this.$emit("input", this.listToString(this.fileList));        this.$modal.closeLoading();      }    },    // 预览    handlePictureCardPreview(file) {      this.dialogImageUrl = file.url;      this.dialogVisible = true;    },    // 对象转成指定字符串分隔    listToString(list, separator) {      let strs = "";      separator = separator || ",";      for (let i in list) {        if (list[i].url) {          strs += list[i].url.replace(this.baseUrl, "") + separator;        }      }      return strs != "" ? strs.substr(0, strs.length - 1) : "";    },  },};</script><style scoped lang="scss">// .el-upload--picture-card 控制加号部分::v-deep .hide .el-upload--picture-card {  display: none !important;}// 去掉动画效果::v-deep .el-list-enter-active,::v-deep .el-list-leave-active {  transition: all 0s;}::v-deep .el-list-enter,.el-list-leave-active {  opacity: 0;  transform: translateY(0);}.img-box {  width: 100%;  height: 100%;  position: relative;  .img-model {    width: 100%;    display: none;    position: absolute;    left: 0;    top: 0;    align-items: center;    > span {      background-color: rgba(30, 30, 30, 0.3);      display: block;      padding: 5px;      color: #fff;      text-shadow: 0 0 2px #1e1e1e;    }  }  &:hover {    .img-model {      display: block;    }  }}</style>
 |