customUploadMulti.vue 5.15 KB
<template>
  <div>
    <el-input clearable v-model="uploadImgUrl" size="mini" @change="changeInput">
      <template slot="append">
        <i class="iconfont iconfolder-o" @click="dialogVisible = true"></i>
      </template>
    </el-input>


    <!-- 弹窗 -->
    <el-dialog title="图库" :visible.sync="dialogVisible" top="1vh">
      <el-button size="medium" type="info" icon="el-icon-upload2" @click="uploadHandler">点击上传</el-button>
      <input type="file" class="file" ref="files" @change="getImages" />
      <div class="title">可选列表</div>
      <div class="image-list">
        <el-image class="image" v-for="item in fileList" :key="item.fileId" :src="item.urlPath" lazy
          @click="imageClickHander(item)"></el-image>
      </div>
      <div class="title">已选列表</div>
      <div class="image-selected-list">
        <template v-for="item in selectedFileList">
          <el-image class="image" :key="item.fileId" :src="item.urlPath"></el-image>
          <i class="close el-icon-delete" @click="deleteFileHandler(item)"></i>
        </template>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import axios from "axios";
import { getToken } from "@/utils/auth";
import { getFielList } from "@/api/file"
export default {
  name: 'custom-upload-multi',
  model: {
    prop: "value",
    event: "input"
  },
  props: {
    value: {
      type: "",
      default: ""
    }
  },
  data() {
    return {
      dialogVisible: false, // 弹窗状态
      requestUrl: process.env.BASE_API + "/file/upload",
      headers: {
        Authorization: getToken()
      },
      fileList: [], // 图片列表
      selectedFileList: [], // 选中的图片列表
      uploadImgUrl: ""
    };
  },
  async created() {
    this.uploadImgUrl = this.value.trim();
    await this.getFielList();
    this.getSelectedFileList();
  },
  methods: {
    // 获取图片列表
    async getFielList() {
      const rs = await getFielList();
      if (rs.code === 200 || rs.code === "200") {
        let fileList = rs.data;
        fileList.reverse();
        this.fileList = fileList;
      }
    },
    // 获取已选中图片列表
    getSelectedFileList() {
      const urlPathList = this.uploadImgUrl.split(',');
      urlPathList.forEach(url => {
        const temp = this.fileList.find(item => item.urlPath === url);
        temp && this.selectedFileList.push(temp);
      });
    },
    uploadHandler() {
      this.$refs.files.click();
    },
    getImages(el) {
      const file = el.target.files[0];
      const type = file.type.split("/")[0];
      if (type === "image") {
        this.upload(file);
      } else {
        this.$message.warning("只能上传图片格式")
      }
    },
    // 图片上传
    upload(file) {
      let that = this;
      let formdata = new FormData();
      formdata.append("file", file);
      axios
        .post(this.requestUrl, formdata, {
          headers: that.headers
        })
        .then(response => {
          let res = response.data;
          if (res.code === "200") {
            this.getFielList();
          }
        });
    },
    // 文本框url改变
    changeInput() {
      this.$emit("input", this.uploadImgUrl);
      this.$emit("change", this.uploadImgUrl);
    },
    // 图片点击事件
    imageClickHander(item) {
      if (!this.selectedFileList.includes(item)) {
        this.selectedFileList.push(item);
      }
    },
    // 删除已选图片
    deleteFileHandler(item) {
      this.selectedFileList = this.selectedFileList.filter(value => {
        return value.fileId !== item.fileId;
      });
    },
    // 确定按钮
    confirm() {
      const urlList = this.selectedFileList.map(item => {return item.urlPath});
      const urlPath = urlList.toString();
      this.$emit("input", urlPath);
      this.$emit("change", urlPath);
      this.dialogVisible = false;
    }
  }
};
</script>
<style lang="scss" scoped>
.file {
  display: none;
}

:deep(el-input-group__append),
:deep(el-input-group__prepend) {
  padding: 0 10px !important;
  overflow: hidden;
}

.iconfont {
  cursor: pointer;
  font-size: 12px;
}


:deep(.el-dialog .el-dialog__header),
:deep(.el-dialog__body),
:deep(.el-dialog__footer) {
  background: #1b1e25;
}

.image-list {
  margin-top: 20px;
  height: 40vh;
  overflow: auto;

  &::-webkit-scrollbar {
    /*滚动条整体样式*/
    width: 8px;
    /*高宽分别对应横竖滚动条的尺寸*/
    height: 1px;
  }

  &::-webkit-scrollbar-thumb {
    /*滚动条里面小方块*/
    border-radius: 10px;
    background: #535353;
  }

  &::-webkit-scrollbar-track-piece {
    /*滚动条里面轨道*/
    border-radius: 10px;
    background: #1b1e25;
  }

  .image {
    width: 20%;
    padding: 0 0.5px 0 0.5px;
    min-height: 90px;

    :deep(el-image__error) {
      width: 100%;
      height: 100%;
      min-height: 90px;
    }
  }
}

.image-selected-list {
  @extend .image-list;
  height: 20vh;
  position: relative;

  .close {
    color: #FFFFFF;
    cursor: pointer;
  }
}

.title {
  color: #909399;
}
</style>