ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-03-31 11:02:14  阅读:232  来源: 互联网

标签:word attachments url fileList item state VUE3.0 const xls


最近好几个项目需要上传附件,之前用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有