1. 程式人生 > 其它 >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

最終效果圖 檔案上傳效果

圖片上傳效果

 

 圖片預覽效果