其他分享
首页 > 其他分享> > VUE3.0 多附件上传,支持word、xls、pdf、png

VUE3.0 多附件上传,支持word、xls、pdf、png

作者:互联网

最近好几个项目需要上传附件,之前用vue2.0写了一版,在原来基础上修改了一下,整合到vue3.0的项目中,使用vue3-preview-image对图片加上图片预览功能,不多说了,直接贴代码吧,需要的自拿。

新建attachment.vue文件

<template>
  <div>
    <div class="divattachlist">
      <div v-for="(f, i) of attachments" :key="i" :class="[!!f.type && f.type.indexOf('image') > -1 ? 'isimgdiv' : 'notimgdiv']">
        <div v-if="!!f.type && f.type.indexOf('image') > -1" style="position: relative;">
          <img v-if="isedit" src="@/assets/images/attachment/smalldel.png" class="imgdel1" @click="fileRemoveClick(f)" />
          <img :src="getObjectURL(f)" class="img1" @click="handleClick(f, $event)" />
        </div>
        <div v-else>
          <a v-if="!isedit" :href="getObjectURL(f)" style="display: flex; align-items: center;">
            <img :src="gettypeimg(f.type)" style="width:2rem;height:2rem;margin:0 10px 0 0" />
            <div style="flex:1" @click="previewFile(f, $event)">{{f.name }}</div>
          </a>
          <div v-if="isedit" style="display: flex; align-items: center;">
            <img :src="gettypeimg(f.type)" style="width:2rem;height:2rem;margin:0 10px 0 0" />
            <div style="flex:1" @click="previewFile(f, $event)">{{ f.name }}</div>
            <img src="@/assets/images/attachment/smalldel.png" style="width:1rem;height:1rem;margin-left: 1rem;" @click="fileRemoveClick(f)" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, toRefs, reactive, onMounted, watch, getCurrentInstance, nextTick } from 'vue';
import { batchupload } from "@/service/index.js";
import { preview } from 'vue3-preview-image' // 使用setup组合式api时引入方法调用
export default {
  components: {

  },
  name: "attachments",
  props: ["attachments", "isedit"],
  setup(props, context) {
    const state = reactive({
      previewpp: false,
      previewurl: "",
      srcList: [],
      isedit: false,
      attachments: {},
      attachfileids: []//附件上传后的id数组;
    })
    onMounted(() => {

    })
    const handleClick = (f, evt) => {
      state.previewurl = f.url || evt.currentTarget.currentSrc;
      state.previewpp = true;
      //预览图片
      preview(0, state.srcList, 'url');
    }
    const fileRemoveClick = (f) => {
      state.attachments.splice(state.attachments.indexOf(f), 1)
    }
    const getObjectURL = (file) => {
      var url = null;
      if (file.url) {
        url = file.url;
      } else if (window.createObjectURL != undefined) { // basic
        url = window.createObjectURL(file);
      } else if (window.URL != undefined) { // mozilla(firefox)
        url = window.URL.createObjectURL(file);
      } else if (window.webkitURL != undefined) { // webkit or chrome
        url = window.webkitURL.createObjectURL(file);
      }
      if (url != "") {
        state.srcList.push({ 'url': url })
      }
      return url;
    }

    const gettypeimg = (type) => {
      let url = "src/assets/images/attachment/unknowfile.png";
      switch (type) {
        case "application/msword":
        case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
          url = "src/assets/images/attachment/word.png";
          break;
        case "application/vnd.ms-excel":
        case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
          url = "src/assets/images/attachment/excel.png";
          break;
        case "application/pdf":
          url = "src/assets/images/attachment/pdf.png";
          break;
        case "application/x-zip-compressed":
        case "application/x-gzip":
          url = "src/assets/images/attachment/zip.png";
          break;
        default:
          break
      }
      return url;
    }
    //文件预览
    const previewFile = (file, evt) => {
    }
    //上传附件
    const uploadFile = reactive(async () => {
      state.attachfileids = [];
      let fd2 = new FormData();
      state.attachments.forEach(item => {
        if (item.fileid) {// 已上传的。
          state.attachfileids.push(item.fileid);
        } else {
          fd2.append("files", item);
        }
      })
      if (fd2.get("files") != null) {
        let p2 = batchupload(fd2);
        await Promise.all([p2]).then(rs => {
          // 2、附件
          let attachdata = rs[0].data;
          if (attachdata.code == "200" && attachdata.data.length > 0) {
            attachdata.data.forEach(item => {
              state.attachfileids.push(item.id);
            })
          }
        })
      }
      return state.attachfileids;
    })

    watch(() => props.attachments, (newVal, oldVal) => {
      state.attachments = newVal;
      state.srcList = [];
    },
      // { immediate: true }// 解决首次无法watch的问题
    )
    watch(() => props.isedit, (newVal, oldVal) => {
      state.isedit = newVal;
    },
      //{ immediate: true }// 解决首次无法watch的问题
    )
    return {
      ...toRefs(state),
      handleClick,
      fileRemoveClick,
      getObjectURL,
      gettypeimg,
      uploadFile,
      previewFile
    }
  }
}

</script>
<style scoped>
.divattachlist {
  padding-left: 65px;
  margin: 10px 0;
}

.divattachlist .isimgdiv {
  width: 25%;
  display: inline-block;
  text-align: center;
}
.divattachlist .isimgdiv img {
  height: 4.9rem;
  width: 90%;
  margin: 0 11%;
}
.divattachlist .isimgdiv .imgdel1 {
  width: 1rem;
  height: 1rem;
  position: absolute;
  right: 0;
  margin: 0 5%;
}
.divattachlist .isimgdiv .img1 {
  height: 5rem;
  width: 90%;
  margin: 0 4%;
}
.divattachlist .notimgdiv {
  padding: 5px 5px 0 5px;
  font-size: 15px;
}

.previewimg {
  max-width: 96vw;
  max-height: 60vh;
}
.van-popup :deep(.van-popup__close-icon--top-right) {
  top: 5px;
  right: 5px;
}
</style>
View Code

新建test.vue,并在页面中引用attachment.vue,HTML相关代码

 <el-row class="mt5">
            <el-col :span="8">
              <el-form-item label="证书扫描件" prop="certificatefile" label-width="180px">
                <img :v-slot="trigger" style="height:20px;width:18px;cursor:pointer" src="@/assets/images/attachment/attach.png" alt="选择文件" @click="choiceFile" v-show="disabled" />
                <input type="file" accept=".jpg,.png,.xls,.doc,.pdf" id="fileinput" ref="fileinput" style="display:none;" @change="fileUploadChange" multiple />
              </el-form-item>
              <Attachments ref="fileAttachments" :attachments="fileList" :isedit="isedit"></Attachments>
            </el-col>
          </el-row>
View Code
import Attachments from '@/components/attachments.vue';
export default {
  components: {
    Attachments
  },
 setup(props, context) {
 
    const state = reactive({
      //上传附件相关属性定义
      fileinput: ref(null),
      fileList: [],//附件
      isedit: true,
      baseUrl: window.REQUEST_EAM_URL,
})
    //选择文件
    const choiceFile = () => {
      state.fileinput.dispatchEvent(new MouseEvent('click'))
    }
    //附件上传
    const fileUploadChange = (event, fileList) => {
      let selfiles = event.currentTarget.files;
      for (let i = 0; i < selfiles.length; i++) {
        let item = selfiles[i];
        if (!!item.type && item.type.indexOf("image") > -1) {
          state.fileList = [item, ...state.fileList];
        }
        else {
          state.fileList = [...state.fileList, item];
        }
      }
    };
    //获取已经上传得图片
    const GetFiles = () => {
      GetCommonFiles(state.formdata.id).then(rs => {
        if (rs.data.code != 200 || !rs.data.data) return;
        let files = rs.data.data;
        if (files) {
          state.fileList = [];
          files.forEach(item => {
            item.name = item.filename;
            item.type = item.filemime;
            item.fileid = item.fileid;
            item.url = state.baseUrl + "/eam-common-file/download/" + item.filepath;
            if (!!item.type && item.type.indexOf("image") > -1) {
              state.fileList = [item, ...state.fileList];
            } else {
              state.fileList = [...state.fileList, item];
            }
          })
        }
      });
    }
}
}
View Code

最终效果图 文件上传效果

图片上传效果

 

 图片预览效果

 

标签:word,attachments,url,fileList,item,state,VUE3.0,const,xls
来源: https://www.cnblogs.com/cartoon/p/16080739.html