vue+elementUI实现多文件上传与预览功能实战记录(word/PDF/图片/docx/doc/xlxs/txt)

目录
  • 需求
  • 实现需求
    • 1、利用on-preview+window.open()实现简易版预览效果
    • 2、封装组件实现更完整的上传完成、预览功能
  • 追加关于问的比较多的问题回复
    • 1、imgsrc路径
    • 2、显示原本elementui的那个上传样式
    • 3、file.response显示没有这个属性和方法
    • 4、https://view.officeapps.live.com/op/view.aspx?src=${data}是干嘛的?预览PDF需要安装其他的插件吗?
  • 总结

需求

最近在做vue2.0+element UI的项目中遇到了一个需求:需求是多个文件上传的同时实现文件的在线预览功能。需求图如下:

看到这个需求的时候,小栗脑袋一炸。并不知道该如何下手,之前的实践项目中也并没有遇到相似的功能。因此也废了一番功夫想要实现这样一个功能。

首先先查看elemnt UI的官方文档发现,大部分的实现文件上传效果的功能,即使可以提供预览的功能,但是不能指定该功能的样式和内容有一定的局限性

然后小栗查找“多文件上传预览、PDF预览、word预览等关键词”,发现大部分的大佬的方法都是实现了图片预览,并没有实现多文件上传(也可能是因为我并没有找到相关的功能)。

因此小栗决定自己封装这个功能,并希望有朋友能在这个的基础上进行调整优化。期待你们的参与哦~~

话不多说,上才艺

实现需求

1、利用on-preview+window.open()实现简易版预览效果

查看element UI文档后发现el-upload里面有一个Attribute叫on-preview( 点击文件列表中已上传的文件时的钩子)是专门用来做文件预览的。点击文件就可以出发该函数。再结合window.open()方法可以直接完成一个新开窗口页的查看文件

代码如下:

HTML部分

//on-preview="Previewf"是必须的也是预览的关键
 <el-upload
           class="upload-demo"
           :action="uploadUrl"
           :on-success="handlePreview"
           :on-remove="handleRemove"
           :before-upload="beforeUpload"
           :on-preview="Previewf"
           multiple
           :limit="5"
           :on-exceed="handleExceed"
           :file-list="file-list"
           :accept="accepts"
         >
           <el-button icon="el-icon-upload2" @click="uploadFileClick($event)"
             >上传文件</el-button
           >
         </el-upload>

methods部分

Previewf(file) {
      console.log(file);
      // window.open(file.response)
      if (file) {
        const addTypeArray = file.name.split(".");
        const addType = addTypeArray[addTypeArray.length - 1];
        console.log(addType);
        if (addType === "pdf") {
          let routeData = this.$router.resolve({
            path: "/insurancePdf",
            query: { url: file.response, showBack: false },
          });
          window.open(routeData.href, "_blank");
        }
        //".rar, .zip, .doc, .docx, .xls, .txt, .pdf, .jpg,  .png, .jpeg,"
        else if (addType === "doc" || addType === "docx" || addType === "xls") {
          window.open(
            "http://view.officeapps.live.com/op/view.aspx?src=" + file.response
          );
        } else if (addType === "txt") {
          window.open(file.response);
        } else if (["png", "jpg", "jpeg"].includes(addType)) {
          window.open(file.response);
        } else if (addType === "rar" || addType === "zip") {
          this.$message({
            message: "该文件类型暂不支持预览",
            type: "warning",
          });
           return false;
        }
      }
    },

功能预览

点击蓝色的文件部分就可以出现新开页面,这个简易的利用element UI就完成了这个功能啦~有没有觉得还是不那么难呢?

2、封装组件实现更完整的上传完成、预览功能

上述的功能可以完成预览,但与我们的需求有一部分的出入,不能够完全满足我的业务需求,因此在element UI的基础上,我进行了组件封装,以求完成以下功能:

话不多说,还是上代码:

HTML部分

/*
重点关注的代码:
	:show-file-list="false"
	ref="contentWrap
*/
 <el-upload
            class="upload-demo"
            ref="uploadCom"
            :show-file-list="false"
            :action="uploadUrl"
            :on-success="onSuccess"
            :on-remove="handleRemove"
            :before-upload="beforeUpload"
            multiple
            :limit="5"
            :on-exceed="handleExceed"
            :file-list="file-list"
            :accept="accepts"
          >
            <el-button icon="el-icon-upload2" @click="uploadFileClick($event)"
              >将文件拖到此处,或<em>点击上传</em></el-button
            >
            <div slot="tip" class="el-upload__tip">
              支持扩展名:.rar .zip .doc .docx .xls .txt .pdf .jpg .png .jpeg,最多上传5个文件,每个大小不超过50Mb
            </div>
          </el-upload>
          <div class="flex mt20" v-if="file-list.length > 0">
                <div
                  class="items-wrap"
                  ref="contentWrap"
                  :style="wrapHeight <= 70 ? 'height: auto' : `height: 60px;`"
                  :class="{ noHidden: noHidden }"
                >
                  <uploadfile-item
                    v-for="(item, index) in file-list"
                    :key="index"
                    :file="item"
                    @cancel="cancelFile"
                    :showDel="true"
                    class="mr20"
                  ></uploadfile-item>
                </div>
                <div
                  class="on-off"
                  v-if="wrapHeight > 70"
                  @click="noHidden = !noHidden"
                >
                  {{ noHidden ? "收起" : "更多" }}
                </div>
              </div>

methods部分

import UploadfileItem from "";
export default {
  components: {
    UploadfileItem,
  },
  data() {
    return {
      noHidden: true,
      wrapHeight: 0,
      delDialogitem: 0,
      imgLoad: false,
      centerDialogVisible: false,
     file-list:[],
      },
    };
  },
  methods: {
    cancelFile(file) {
      console.log(file);
    },

    // 上传文件只能添加五条
    uploadFileClick(event) {
      if (this.formLabelAlign.annex.length === 5) {
        this.$message({
          type: "warning",
          message: "最多只可以添加五条",
        });
        event.stopPropagation();
        return false;
      }
    },
    //
    onSuccess(response, file, annex) {
      if (!response) {
        this.$message.error("文件上传失败");
      } else {
        this.imgLoad = false;
        this.$message({
          message: "上传成功!",
          type: "success",
        });
      }
    },

    beforeUpload(file) {
     console.log(file);
    },
    handleExceed(files, ) {
 		console.log(file);
  },
};

UploadfileItem组件内容

<template>
  <div class="file-style-box">
    <div class='upload-file-item'>
      <img :src="imgsrc[getEnd(file.fileName)]" alt="">
      <div>
        <p class='file-name'>
          <span class='name'>{{file.fileName}}</span>
          </p>
        <div class='option'>
          <span class='size'>{{file.size | toKB}}kb</span>
          <div>
            <span v-if='showDel && (isPdf(file) || isImg(file))' @click='previewHandler(file.url)' class='preview mr10'>预览</span>
            <a v-if='!showDel' @click='downLoadHandler' class='preview' :href="file.url" rel="external nofollow" >下载</a>
            <span v-if='showDel' class='mr10 success'>上传完成</span>
          </div>
        </div>
        <div class='delBtn' v-if='showDel' @click='cancelHanlder(file)'>
          <img src="@/assets/public/tips-err.png" alt="">
        </div>
      </div>
    </div>
    <el-dialog
      title="图片预览"
      width="800px"
      class="imgDlgBox"
      :visible.sync="imgDlgVisible"
      :close-on-click-modal="true"
      :modal="false"
      append-to-body
    >
      <img :src="imgUrl" alt="">
    </el-dialog>
  </div>

</template>

<script>
export default {
  props: {
    file: {
      type: Object,
      default: {}
    },
    showDel: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      imgDlgVisible: false,
      imgUrl: '',
      pdfUrl: '',
      imgsrc: {
      /*
		*imgsrc 是关于内部静态图片的显示的路径,需要自己设置
		*示例"xls": require('@/assets/image/xls.png'),
		xis的文件所需要加载的路径是;assets文件下的image文件夹下的xls.png
	*/
        "rar": require('@'),
        "zip": require('@'),
        "pdf": require('@'),
        "jpg": require('@'),
        "jpeg": require('@'),
        "png": require('@'),
        "doc": require('@'),
        "docx": require('@'),
        "txt": require('@'),
        "xls": require('@/assets/image/xls.png'),
      }
    }
  },
  filters: {
    toKB(val) {
      return (Number(val) / 1024).toFixed(0);
    }
  },
  methods: {
    cancelHanlder(item) {
      this.$emit('cancel', item)
    },
    previewHandler(data) {
      if (data) {
        const addTypeArray = data.split(".");
        const addType = addTypeArray[addTypeArray.length - 1];
        if (addType === "pdf") {
          let routeData = this.$router.resolve({ path: "/insurancePdf", query: { url: data, showBack: false } });
          window.open(routeData.href, '_blank');
        } else if (addType === "doc") {
          window.open(
            `https://view.officeapps.live.com/op/view.aspx?src=${data}`
          );
        } else if (addType === "txt") {
          window.open(`${data}`);
        } else if (['png','jpg','jpeg'].includes(addType)) { // 图片类型
          this.imgDlgVisible = true
          this.imgUrl = data
        }
      }
    },
}
</script>
<style lang='scss'>
.file-style-box {
  padding: 10px 10px 0 0;
}
.imgDlgBox {
  .el-dialog {
    .el-dialog__body {
      text-align: center;
      img {
        width: 700px;
        height: auto;
      }
    }
  }
}
.upload-file-item {
  background: #FAFAFA;
  border-radius: 4px;
  padding: 5px 10px;
  margin-bottom: 10px;
  display: flex;
  font-size: 14px;
  width: 236px;
  box-sizing: border-box;
  position: relative;
  img {
    width: 32px;
    height: 40px;
    margin-top: 5px;
    margin-right: 10px;
  }
  .option {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .file-name {
    width: 163px;
    display: flex;
    flex-wrap: nowrap;
    font-size: 14px;
    color: #333;
    font-weight: 400;
    .name {
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
    .end {
      flex: 0 0 auto;
    }
    .el-button{
      border: none;
      padding: 0px;
      width: 90%;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
  .size {
    color: #969696;
  }
  .success {
    color: #78C06E;
  }
  .delBtn {
    position: absolute;
    top: -14px;
    right: -18px;
    cursor: pointer;
    img {
      width:16px;
      height:16px
    }
  }
  // .del {
  //   color: #E1251B;
  //   cursor: pointer;
  // }
  .preview {
    color: #0286DF;
    cursor: pointer;
  }
  .mr10 {
    margin-right: 10px;
  }
}
</style>

效果图

以上就可以实现实现多文件上传+预览(word/PDF/图片/docx/doc/xlxs/txt)啦,希望这样的实现方式也对你有帮助哦

追加关于问的比较多的问题回复

1、imgsrc路径

imgsrc: {
"rar": require('@/assets/material/zip.png'),
}
这个位置会报错

这里报错是因为此处的内容是静态资源,他是我们预览图片的一些细节,长成如下图所示:

你本地应该也需要配置这样一个文件夹的路径就可以啦。

2、显示原本elementui的那个上传样式

重点关注el- upload的代码
:show-file-list="false" //关闭原来的上传样式
ref="contentWrap //这个是通过父子组件传值将子组件的页面

3、file.response显示没有这个属性和方法

file.response是element UI的内置的组件的方法,引入element UI使用文件上传组件就可以实现
    我之前写这儿的file.response 时候,有一个传递值也有问题,好像是element UI的钩子函数的问题,你先打印file。然后看是不是file.response ,不是的话 查看一下file的其他属性,有一个是跟回调相关的返回值
    就可以解决啦

4、https://view.officeapps.live.com/op/view.aspx?src=${data}是干嘛的?预览PDF需要安装其他的插件吗?

首先:不需要再安装其他预览资源加载包,所有的预览都是通过windom.open()方法打开一个新窗口预览。
    PDF的预览时使用的office官方的接口文档:`https://view.officeapps.live.com/op/view.aspx?src=${data}就可以预览PDF文档了。
    图片的预览是通过dialog的弹窗实现的,就简单一个弹窗
    rar和zip不支持预览,只能下载查看

总结

到此这篇关于vue+elementUI实现多文件上传与预览功能(word/PDF/图片/docx/doc/xlxs/txt)的文章就介绍到这了,更多相关vue+elementUI多文件上传预览内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • element-ui多文件上传的实现示例

    上传方案一: 先将文件上传到七牛,再将七牛上传返回的文件访问路径上传到服务器 <div class="upload-music-container"> <el-upload class="upload-music" ref="upload" action="http://up-z2.qiniup.com/" :data="{token:uploadToken}" multiple acce

  • element-ui 文件上传修改文件名的方法示例

    技术背景 Vue + axios + element-ui 问题的产生 一个美好的周五,我正在愉快地打着代码,突然收到一封来自产品的神秘消息,线上活动出 BUG 了!呐尼!怎么可能!一定是你的打开方式不对!打开消息截图,线上的一个聊天室背景突然变成了另一张毫无关联的图(一个大大的太阳),我一看,这不是我刚刚上传的一个图嘛!为什么跑到那里去了! 问题定位 我们所有的静态资源(比如图片)都会上传到一个服务器上,在活动中访问时会统一访问静态资源服务器,而静态资源上传时并没有处理重名问题!!!接口侧仅仅

  • element-ui中el-upload多文件一次性上传的实现

    项目需求是多个文件上传,在一次请求中完成,而ElementUI的上传组件是每个文件发一次上传请求,因此我们借助FormData的格式向后台传文件组 html代码 <div class="upload-file"> <el-upload accept=".xlsx" ref="upload" multiple :limit="5" action="http://xxx.xxx.xxx/personal

  • VUE+element-ui文件上传的示例代码

    目录 图片上传(ImageCropper) 文件上传(el-upload) 注意 图片上传(ImageCropper) 此前端代码自己封装了文件上传,只需要配置后端接口需求URL以及对应的图片上传成功后的处理函数,后端返回OSS生成的图片访问地址,然后cropsuccess函数将上传成功的图像进行显示. <template> <div class="app-container"> <!-- 讲师头像 --> <el-form-item labe

  • vue elementUI 处理文件批量上传方式

    目录 elementUI 如何处理文件批量上传 问题 解决 elementUI批量上传下载注意事项 在el-upload组件关键的钩子,其它省略 点击上传,将多个文件和表单数据一起上传 elementUI 如何处理文件批量上传 问题 elementUI的Upload上传组件,通过设置multiple为true,就可以实现多选文件:但是在处理的时候还是一个一个传上去.目前需要在所有文件上传后,将某几个上传错误的结果拼接起来做一次提醒 解决 this.$refs.upload.uploadFiles

  • element-ui 中使用upload多文件上传只请求一次接口

    方法一 不使用组件内部的钩子 <el-upload class="upload-image" ref="upload" multiple :action="baseUrl" list-type="picture" :auto-upload="false" accept="image/*"> <el-button slot="trigger" size

  • vue+elementUI实现多文件上传与预览功能实战记录(word/PDF/图片/docx/doc/xlxs/txt)

    目录 需求 实现需求 1.利用on-preview+window.open()实现简易版预览效果 2.封装组件实现更完整的上传完成.预览功能 追加关于问的比较多的问题回复 1.imgsrc路径 2.显示原本elementui的那个上传样式 3.file.response显示没有这个属性和方法 4.https://view.officeapps.live.com/op/view.aspx?src=${data}是干嘛的?预览PDF需要安装其他的插件吗? 总结 需求 最近在做vue2.0+eleme

  • JQ图片文件上传之前预览功能的简单实例(分享)

    1.先准备一个div onchange触发事件 <input type="file" onchange="preview(this)" ></span> <div id="preview"></div> 2.写JS代码 //上传图片之前预览图片 function preview(file){ if (file.files && file.files[0]){ var reader =

  • JS中FileReader类实现文件上传及时预览功能

    FileReader是H5浏览器才支持的JS类,如果不支持H5de浏览器可以使用FormData类实现文件的上传预览,使用可以参考我的下一篇博客:JS中FormData类实现文件上传 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="wid

  • js图片上传前预览功能(兼容所有浏览器)

    网上找到的一份文件上传前预览的代码,转自JavaScript 图片的上传前预览(兼容所有浏览器) <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <style type="text/css"> #preview, .img, img { w

  • uploadify java实现多文件上传和预览

    本文实例为大家分享了java文件上传和预览实现代码,供大家参考,具体内容如下 1.下载uploadify插件 2.index.html <!DOCTYPE html> <html lang="en"> <head> <@head/> <script src="<@path/>/js/uploadify-v3.1/jquery.uploadify-3.1.js"></script> &

  • servlet实现文件上传、预览、下载、删除功能

    servlet实现文件上传,预览,下载和删除,供大家参考,具体内容如下 一.准备工作: 1.1 文件上传插件:uploadify: 1.2 文件上传所需jar包:commons-fileupload-1.3.1.jar和commons-io-2.2.jar 1.3 将数据转成JSON对象需要jar包:commons-beanutils-1.8.3.jar.commons-collections-3.2.1.jar.commons-lang-2.6.jar.commons-logging-1.1.

  • BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤

    bootstrap-fileinput源码:https://github.com/kartik-v/bootstrap-fileinput bootstrap-fileinput在线API:http://plugins.krajee.com/file-input bootstrap-fileinput Demo展示:http://plugins.krajee.com/file-basic-usage-demo 这个插件主要是介绍如何处理图片上传的处理操作,原先我的Excel导入操作使用的是Upl

  • AngularJS实现图片上传和预览功能的方法分析

    本文实例讲述了AngularJS实现图片上传和预览功能的方法.分享给大家供大家参考,具体如下: html5原生方法 先看一下html5原生方法上传和预览图片的实现: // <img id="img-preview"> var imgPreview = document.getElementById("img-preview"); // <input id="img-input" type="file">

  • JavaScript实现单图片上传并预览功能

    本文实例为大家分享了JavaScript实现单图片上传并预览功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>单图片上传并实现预览</title> <style> /*上传图片*/ .addPerson{ line-height: 190px; } .a

  • ThinkPHP5+Layui实现图片上传加预览功能

    html代码 <div class="layui-upload"> <button type="button" class="layui-btn" id="cover">上传封面</button> </div> <div class="layui-input-inline"> <img id="preview" width

随机推荐