Vue3 实现文件上传、下载、在线预览功能,小记

346 阅读2分钟

一、使用element-plus upload实现上传

  <el-upload
      class="upload-demo"
      action="/manage/file/upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleAvatarSuccess"
      name="uploadFile"
      :headers="headers"
      :on-error="onerror"
    >
      <el-button v-if="show" type="primary">上传附件</el-button>
    </el-upload>

这里遇见一个坑

记录一下 Element plus Upload 上传 开发没问题打包上线后报错TypeError: ee.upload.addEventListener is no a function

查找了网上资料,可能是因为在打包后,文件的路径或者名称发生了变化,导致代码中的某些方法无法正确找到。 解决办法

1.在文件node_modules/dist/mock.js中找到第8311行添加

MockXMLHttpRequest.prototype.upload = xhr.upload;

image.png

2.2、文件node_modules/mockjs/src/xhr/xhr.js  第216行添加以下代码:

MockXMLHttpRequest.prototype.upload = xhr.upload;

image.png 大佬原文 blog.csdn.net/liuzaixi/ar…

文件下载

import axios from 'axios';
import { useUserStore } from '@/store';

export const downLoadTemplate = (filename: string) => {
  const userStore = useUserStore();
  const headers: any = {
    Authorization: userStore.token,
    'Access-Control-Allow-Origin': '*'
  };
  axios
    .get(`/manage/file/download?filename=` + filename, {
      responseType: 'blob',
      // 请求头添加token
      headers
    })
    .then((res) => {
      if (res.status === 200) {
        const elink = document.createElement('a');
        // 使用后端提供的文件名  命名
        elink.style.display = 'none';
        // 文件下载地址赋值
        elink.href = window.URL.createObjectURL(res.data);

        // 自定义文件名
        elink.download = filename;
        // 调用a标签单击事件进行下载文件
        elink.click();
        console.log('文件导出成功');
        ElMessage.success('文件下载成功');
      }
    })
    .catch((err) => {
      console.log(err, '打印错误信息');
      ElMessage.error('文件下载失败');
    });
};

文件预览

这里找到一个非常好用的插件vue-office支持多种文件(docx、pdf、excel)预览的vue组件套装,支持vue2/3。具体使用方法可以直接查看官方文档,非常方便, 然后图片预览我使用了,因为我的图片地址也是文件流的需要转一下就用了下面的方法 <el-image :src="url" />

<template>
  <div class="demo-image__preview" v-loading="loading">
    <el-image :src="url" />
  </div>
</template>

<script lang="ts" setup>
import { useUserStore } from '@/store';
import { ref } from 'vue';
import axios from 'axios';
const props = defineProps({
  filename: {
    type: String,
    required: true
  }
});
const loading = ref(true);
const url: any = ref('');
const userStore = useUserStore();
const headers: any = {
  Authorization: userStore.token,
  'Access-Control-Allow-Origin': '*'
};
axios({
  method: 'get',
  url: '/manage/file/download?filename=' + props.filename,
  responseType: 'blob',
  headers
})
  .then((res) => {
    let blob = new Blob([res.data], { type: 'image/jpeg' });
    const imageUrl = URL.createObjectURL(blob);
    url.value = imageUrl;
    loading.value = false;
  })
  .catch((err) => {
    console.log('导出失败', err);
  });
</script>

<style scoped>
.demo-image__error .image-slot {
  font-size: 30px;
}
.demo-image__error .image-slot .el-icon {
  font-size: 30px;
}
.demo-image__error .el-image {
  width: 100%;
}
</style>