前言

vue 举例,这样写起来更方便。

一、绘制样式

  1. 绘制两个标签,一个 <div></div> ,一个 <input type="file" />

  2. <div></div>添加 css 样式,并隐藏 <input type="file" />

  3. 点击 <div></div> 标签时,调用 <input type="file" />

.vue

<div @click="clickUploader">点击此处上传文件,可以给我添加各种样式哦</div>
<input type="file" style="display: none" ref="uploader" @change="fileChange" />

二、逻辑处理

考虑到项目中可能不止一个地方使用文件上传,为了方便复用,可以把上传的逻辑抽离出来,单独放到一个文件中。

src 目录下创建 mixins 文件夹,在此文件下创建一个 file.js 文件。

file.js

import { upload } from "@/api/file.js";

export default {
  methods: {
    fileUpload(file) {
      let parma = new FormData();
      parma.append("file", file);
      return new Promise((resolve, reject) => {
        upload(parma)
          .then((res) => {
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      });
    },
  },
};
  • 注意1:上传的文件需要放在 FormData 对象中。
  • 注意2:对象中的 key 值视具体情况而定,此处的 file 只是举例。
  • 注意3:FormData 对象添加新属性的方法是 append(key, value)

vue 中的代码如下,引入上面写的 js ,点击 div ,调用 <input type="file" />,并执行上传文件的方法。

.vue

<template>
  <div>
    <div @click="clickUploader">点击此处上传文件</div>
    <input type="file" style="display: none" ref="uploader" @change="fileChange" />
  </div>
</template>

<script>
import file from "@/mixins/file";
export default {
  mixins: [file],
  data() {
    return {
      uploadFileList: [],
    };
  },
  methods: {
    // 文件上传
    clickUploader() {
      this.$refs.uploader.click();
    },
    // 选择文件
    fileChange(e) {
      this.fileUpload(e.target.files[0]).then((res) => {
        this.uploadFileList = [...this.uploadFileList, res];
      });
      e.target.value = null; // 清除 input 中的值
    },
  },
};
</script>
  • 注意1:用混入的方式引入 file.js 文件。
  • 注意2:上传完成后需要清除 input 中的值,否则无法上传重复文件。

三、图片压缩

现在的手机拍照像素都很高,照片动辄十几 Mb ,如果把这么大的文件上传,必然会导致上传速度慢,且会造成极大的资源浪费,因此,需要对图片进行压缩。

延伸: 除图片外,其它大文件也可以进行处理,比如分段式上传,不过本文对此不做赘述,有需要的可自行百度。

图片压缩的原理是把图片转成 canvas ,因为 canvas 的宽高和分辨率可以自定义,所以可以将其压缩至指定大小,这个功能并不复杂,不过这个功能已经有人做出了插件 image-conversion ,本文不对具体实现过程和原理进行分析,仅介绍插件的使用方法。

npm i image-conversion --save
import * as imageConversion from 'image-conversion';

return new Promise((resolve, reject) => {
  imageConversion.compressAccurately(file, 800).then((res) => {
    resolve(res);
  });
});

四、附:文件后缀名提取

.js

export default {
  methods: {
    // 获取文件格式(此处是为了显示不同文件图标,并对图标添加自定义颜色,具体可根据需求进行修改)
    fileType(e) {
      if (!e) {
        return false;
      }
      let [list, fileIcon, format] = [
        e.split("."),
        {
          icon: null,
          color: null,
        },
      ];
      format = list[list.length - 1];
      let format = list[list.length - 1];
      switch (format) {
        case "xls":
          fileIcon = {
            icon: "icon-ECEL",
            type: "xls",
            color: "",
          };
          break;
        case "xlsx":
          fileIcon = {
            icon: "icon-ECEL",
            type: "xlsx",
            color: "",
          };
          break;
        case "doc":
          fileIcon = {
            icon: "icon-WORD",
            type: "",
            color: "",
          };
          break;
        case "docx":
          fileIcon = {
            icon: "icon-WORD",
            type: "docx",
            color: "",
          };
          break;
        case "pptx":
          fileIcon = {
            name: "icon-PPT",
            type: "pptx",
            color: "",
          };
          break;
        case "png":
          fileIcon = {
            icon: "icon-PNG",
            type: "png",
            color: "",
          };
          break;
        case "jpg":
          fileIcon = {
            icon: "icon-JPG",
            type: "jpg",
            color: "",
          };
          break;
        case "jpeg":
          fileIcon = {
            icon: "icon-JPG",
            type: "jpeg",
            color: "",
          };
          break;
        case "gif":
          fileIcon = {
            icon: "icon-GIF",
            type: "",
            color: "",
          };
          break;
        case "txt":
          fileIcon = {
            icon: "icon-TXT",
            type: "txt",
            color: "",
          };
          break;
        case "wps":
          fileIcon = {
            icon: "icon-WPS",
            type: "wps",
            color: "",
          };
          break;
      }
      return fileIcon;
    },
  },
};

END

Logo

前往低代码交流专区

更多推荐