el-upload上传文件

news2024/11/20 18:40:37

el-upload上传文件

前言

公司和学校项目都用到了上传文件的功能,记录一下。

准备

express实现的上传接口

const express = require('express');
​
// 文件上传模块
const multiparty = require('multiparty')
​
// 提供跨域资源请求
const cors = require('cors')
​
// 文件操作
const fs = require('fs')
​
const app = express();
​
app.use(cors());
​
app.get('/policy', (req, res) => {
  res.json({
    code: 200,
    msg: '成功',
    url: '/upload',
    filename: 'clz'
  })
});
​
app.post('/upload', (req, res) => {
  let form = new multiparty.Form()
​
  // 配置文件存储路径
  form.uploadDir = './upload'
​
  form.parse(req, (err, fields, files) => {
    // 解析formData
​
    for (const file of files.file) {
      const newPath = form.uploadDir + '/' + file.originalFilename
​
      // renameSync(oldPath, newPath):同步重命名文件,oldPath使用默认上传路径,newPath则是想要保存到的路径
      fs.renameSync(file.path, newPath);
    }
​
    res.json({
      code: 200,
      msg: '上传成功'
    })
  })
});
​
app.listen(8088, () => {
  console.log('http://localhost:8088/');
});

如果需要使用,自行查阅express用法,也可以到本人博客中查看简单教程。

开始

简单使用版本

<template>
  <el-upload
    action="http://localhost:8088/upload"
    :show-file-list="true"
    :on-success="handleSuccess"
    :on-error="handleError"
  >
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
import { ElMessage } from "element-plus";
​
const handleSuccess = (res, file, files) => {
  console.log(res);
  console.log(file, files);
​
  new ElMessage({
    type: "success",
    message: "上传成功",
  });
};
​
const handleError = (error, file, files) => {
  console.log(error);
  console.log(file, files);
  ElMessage.error("上传失败");
};
</script>
​
<style lang="less" scoped>
</style>
​

解释下上面的属性:

  • action:请求URL

  • show-file-list:是否展文件列表(如果没上传成功,则会闪现一下,再消失)

  • on-success:文件上传成功钩子

    • 参数:
    • res:后端返回的成功响应数据(响应状态为成功时)
    • file:上传的文件
    • files:成功上传的文件列表
  • on-success:文件上传失败钩子

    • 参数:
    • error:错误对象,内容是后端返回的响应数据(响应状态为失败时,如状态码为500)
    • file:上传的文件
    • files:成功上传的文件列表

file

接下来,去后端设置的路径去看看有没有成功保存上传的文件。

image-20220508120156380

添加token

这个比较简单,因为element-plus也封装好了,只需要使用headers属性,去设置请求头即可

<el-upload
  action="http://localhost:8088/upload"
  :headers="{ token: '12345' }"
>
  <el-button type="primary">上传图片</el-button>
</el-upload>

image-20220508120607213

上传前获取签名再上传

有时候并不是直接上传就可以的,比如一开始并没有上传路径,需要调用获取签名接口来获取上传路径。这个时候就可以使用我们的上传文件之前的钩子before-upload。在上传前调用获取签名的接口,用拿到的url去修改,上传路径,就能够上传了。

<template>
  <el-upload :action="url" :before-upload="getPolicy">
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
import axios from "axios";
import { reactive, ref } from "vue";
​
const url = ref("");
​
const getPolicy = () => {
  return new Promise((resolve, reject) => {
    axios
      .get("http://localhost:8088/policy")
      .then((res) => {
        const { data } = res;
​
        if (data.code === 200) {
          url.value = `http://localhost:8088${data.url}`;
​
          resolve();
        }
      })
      .catch((error) => {
        reject(error);
      });
  });
};
</script>
​
<style lang="less" scoped>
</style>

image-20220508134523663

手动上传

我们上面的例子都是选中文件后,就会上传,但是有时候我们会有点击按钮才去上传的需求,这个时候就需要结合auto-uploadsubmit来实现手动上传了。先设置auto-uploadfalse,取消自动上传,这个时候选中图片后就没有上传了,所以我们在按钮的点击事件中,还得使用DOM去调用submit方法去手动上传。

<template>
  <el-upload
    ref="upload"
    action="http://localhost:8088/upload"
    :auto-upload="false"
  >
    <el-button type="primary">上传图片</el-button>
  </el-upload>
​
  <el-button type="primary" @click="confirm">确定</el-button>
</template>
​
<script setup>
import { getCurrentInstance } from "vue";
​
const { proxy } = getCurrentInstance();
​
const confirm = () => {
  proxy.$refs.upload.submit();
};
</script>
​
<style lang="less" scoped>
</style>

file

上传的时候修改文件名

情境:调用签名接口时也给你返回一个文件名,前端在上传的时候需要把文件名改掉再上传,让服务器保存的是规范的文件名。

首先,先说一下结论:无法通过修改File对象的name属性,实现重命名

在上传前钩子中修改File对象的name属性

<template>
  <el-upload
    action="http://localhost:8088/upload"
    :before-upload="getPolicy"
  >
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
// 上传前钩子
const getPolicy = (file) => {
  console.log(file);
​
  file.name = "clz.png";    // 如果在上传前钩子中对文件的name属性进行修改,则会导致上传不了。而且不报错,难以发现问题所在。
​
  console.log(file.name);
};
</script>
​
<style lang="less" scoped>
</style>

file

毫无波澜。

上传文件时修改

通过http-request属性,覆盖默认的上传行为。

<template>
  <el-upload action="http://localhost:8088/upload" :http-request="httpRequest">
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
const httpRequest = ({ file }) => {
  console.log(file);
  file.name = "clz.png";
};
</script>
​
<style lang="less" scoped>
</style>

file

直接报错

解决方案

既然不能直接修改File对象的name属性来实现重命名操作,那么应该怎么办呢?

这个时候就需要通过new File构造函数去再创建一个文件,创建的同时更改名字。

<template>
  <el-upload action="http://localhost:8088/upload" :http-request="httpRequest">
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
const httpRequest = ({ file }) => {
  console.log(file);
​
  const cloneFile = new File([file], "clz.png");
​
  console.log(cloneFile);
};
</script>
​
<style lang="less" scoped>
</style>

注意:如果是更改一个文件的文件名的话,File的构造函数第一个参数应该是包住file的数组

image-20220508164215907

但是这个时候,又有问题了,我们已经使用http-request覆盖默认的上传的行为了,所以我们还得重新实现上传。

上传文件首先需要formData对象,然后给formData添加上数据,在把formData通过接口发出去即可。

<template>
  <el-upload action="#" :http-request="httpRequest">
    <el-button type="primary">上传图片</el-button>
  </el-upload>
</template>
​
<script setup>
import axios from "axios";
import { ElMessage } from "element-plus";
​
const httpRequest = ({ file }) => {
  console.log(file);
​
  const cloneFile = new File([file], "clz.png");
​
  const formData = new FormData();
  formData.append("file", cloneFile);
​
  axios.post("http://localhost:8088/upload", formData).then((res) => {
    if (res === 200) {
      new ElMessage({
        type: "success",
        message: "上传成功",
      });
    }
  });
};
</script>
​
<style lang="less" scoped>
</style>

image-20220508165110118

小贴士

上面已经说出解决方法了,但是,重命名一般不会帮你把文件后缀都给改掉。所以这个时候可以通过正则表达式把后缀给取出来。

const houzhui = file.name.replace(/.+./, "");
const newFile = new File([file], filename+houzhui);

一次请求上传多个文件

el-upload默认一个请求上传一个文件。需要上传多个文件首先得添加multiple属性。

file

上面的例子中,我们可以发现,我们上面选中了两个文件,点击确定,上传图片时调用了两次上传接口。

既然el-upload默认一个请求上传一个文件,那么我们就不要使用el-upload的上传方法就行了。点击确定按钮时,去调用一个上传文件方法。

因为我们点击确定时,需要获取选中的文件,所以需要有file-list属性,保存选中的文件。

<template>
  <el-upload
    ref="upload"
    action="#"
    multiple
    :file-list="fileList"
    :auto-upload="false"
  >
    <el-button type="primary">上传图片</el-button>
  </el-upload>
​
  <el-button type="primary" @click="confirm">确定</el-button>
</template>

点击确定按钮,会触发confirm事件,实现一个请求上传多个文件的关键就在这,这个时候创建一个formData对象,遍历选中的文件列表,通过append添加到formData上。最后在调用uploadFile函数,真正把文件上传上去。

const fileList = reactive([]);
​
const confirm = () => {
  const formData = new FormData();
​
  console.log(fileList);
​
  for (const file of fileList) {
    formData.append("file", file.raw);
  }
​
  uploadFiles(formData);
};
​
function uploadFiles(data) {
  axios.post("http://localhost:8088/upload", data).then((res) => {
    if (res === 200) {
      new ElMessage({
        type: "success",
        message: "上传成功",
      });
    }
  });
}

file

小技能

获取图片的宽高像素

// 创建Image对象
const img = new Image();
​
// 设置图片的src
img.src = 'https://www.clzczh.top/medias/featureimages/19.png';
​
// 添加load事件,图片加载完成后执行
img.onload = () => {
  // 获取图片的宽高像素
  console.log(img.width, img.height);
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Idea中使用Tomcat部署并启动Web项目

首先在Idea中选择编辑运行配置&#xff0c;如下图 左上角的“”号&#xff0c;选择Tomcat服务&#xff0c;如下图 自定义服务名称和项目在浏览器的访问路径 配置Tomcat服务器路径&#xff0c;如下图 然后在服务器中部署项目&#xff08;下面的警告提示&#xff1a;Warning: No …

nginx响应码301及访问路径参数丢失之间的关系

nginx响应码301及访问路径参数丢失之间的关系 本文比较长&#xff0c;所以写了一篇比较短的结果导向的文章&#xff0c;换了一下思路&#xff0c;大家可以看一这篇文章&#xff0c;如果感兴趣再来看这篇文章&#xff1a;nginx导致vue设置history模式下的请求丢失参数 背景描述…

Java使用WebStocket实现前后端互发消息

记录一下自己使用WebStocket实现服务器主动发消息的过程和踩得雷。 需求&#xff1a;车牌识别系统识别到车牌后&#xff0c;持续向前端推送车牌信息&#xff0c;直到前端回复收到。 测试需求&#xff1a;新增 客户后&#xff0c;持续向前端推送客户信息&#xff0c;直到前端收…

type=“module“ 你了解,但 type=“importmap“ 你知道吗

新出了一个系列&#xff1a;Vue2与Vue3 技巧小册 有梦想&#xff0c;有干货&#xff0c;微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 当E…

css的rotate3d实现炫酷的圆环转动动画

1.实现效果 2.实现原理 2.1 rotate3d rotate3d&#xff1a;rotate3d() CSS 函数定义一个变换&#xff0c;它将元素围绕固定轴移动而不使其变形。运动量由指定的角度定义; 如果为正&#xff0c;运动将为顺时针&#xff0c;如果为负&#xff0c;则为逆时针。 语法&#xff1a; …

【面试题】redux及中间件相关面试题解析

1、什么是Redux&#xff1f; Redux就是一个js容器&#xff0c;用于全局的状态管理 2、为什么在React项目中要使用Redux&#xff1f; 因为React本质上就是一个UI库&#xff0c;它是单向数据流的&#xff0c;就是说数据只能从父组件通过props流向子组件&#xff0c;但如果子组…

Vue 无感刷新token

关于无感刷新的理解: 实现token无感刷新对于前端来说是一项非常常用的技术,其本质是为了优化用户体验,当token过期时不需要用户跳回登录页重新登录,而是当token失效时,进行拦截,发送刷新token的请求,获取最新的token进行覆盖,让用户感受不到token已经过期 刷新token的一些方案…

零基础JavaScript学习【第六期】

博主有话说:这个礼拜有些忙,离上一次更新已经过了亿天,这几天较忙所以更新会有点慢,谢谢大家的支持。(っ•̀ω•́)っ✎⁾⁾ 我爱学习 个人空间:GUIDM的个人空间 专栏内容:零基础JavaScript学习 基础还是关键。 欢迎大家的一键三连。 前情回顾:第一期https://blog.cs…

uni-app - 最详细 H5 网页接入微信支付功能,提供从详细的示例代码与注释(移动端网页实现微信支付能力,微信公众号前端支付 JSAPI / JS-SDK 详细示例源码)官方最新超级详细教程

前言 关于 uni-app 项目中接入微信支付的文章鱼龙混杂,各种 JSAPI / JS-SDK 乱代码、过时、没注释、不讲流程原理,非常难用。 本文实现了 uni-app H5 移动端网页项目,实现微信支付功能,详细讲解接入流程及超详细示例代码, 从 0-1 完全站在小白的角度,让您无需太多知识也…

【React】React入门--生命周期

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; 文章目录React生命周期初始化阶段运行中阶段销毁阶段老生命周期的问题新生命周期代替性能优化的方案重要的勾子即将废弃的勾子R…

【ElementUI样式优化1】el-table 修改斑马格样式、修改滚动条样式、添加表头边框、删除表格边框划线

重要的不是过去&#xff0c;而是你怎末看待过去&#xff0c;而我们对过去的看法&#xff0c;是可以改变的。 效果预览&#xff1a; &#xff08;1&#xff09;删除表格外框&#xff0c;内框。 &#xff08;2&#xff09;添加表头边框&#xff0c;修改表头文字大小、颜色 &…

猿创征文 |【高级篇】Java 进阶之JVM实战

文章目录⚡前言一、面试题解析二、JVM 理论详解⛅JVM的位置❄️JVM的体系结构⏳类加载器三、JVM 双亲委派机制四、Native 关键字五、PC寄存器 与 方法区六、栈与堆七、三种JVM、新生区、老年区、永久区⛵小结⚡前言 JVM 是 Java 实现 跨平台的基础&#xff0c;所有的Java 程序…

[遇到的问题-已解决]Cannot resolve plugin org.apache.maven.plugins:maven-compiler-plugin:3.1

如上图所示&#xff0c;这是我解决好的&#xff0c;刚开始的时候爆红有这些&#xff1a; 我按照在网上查找的方法&#xff0c;一一试了。 首先&#xff0c;maven 安装的路径和和本地仓库的目录必须要保持一致 打开setting-Build,Excution,Deployment-Build Tools-Maven&#…

vue框架介绍

概述 Vue 是一套用于构建用户界面的渐进式框架 对渐进式的理解&#xff1a; 每个框架都不可避免会有自己的一些特点&#xff0c;从而会对使用者有一定的要求&#xff0c;这些要求有强有弱&#xff0c;它的强势程度会影响在业务开发中的使用方式。 vue的定位&#xff1a; 我在做…

【Vue入门必备知识篇03】--- 生命周期 数据共享

前言❤️ 过好自律的生活&#xff0c;美好才会在路上不期而遇 ❤️【Vue入门必备知识篇03】--- 生命周期 & 数据共享一、生命周期 & 数据共享&#xff08;1&#xff09;组件的生命周期1.1 生命周期 & 生命周期函数1.2 组件生命周期函数的分类1.3 生命周期图示&…

记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题

总结一下自己在把Chrome V2版本的插件升级到V3版本的过程中&#xff0c;遇到的一些问题&#xff0c;之前也有发布一章V3版本的manifest.json配置项参数说明&#xff0c;基本也涵盖了下面提到的几个配置项的改动&#xff0c;传送门>> 总结分了两大块&#xff0c;一块是ma…

【Node.js】深度解析常用核心模块-fs模块

✅ 作者简介&#xff1a;一名将要迈入大三的大学生&#xff0c;致力于提高前端开发能力 ✨ 个人主页&#xff1a;前端小白在前进的主页 &#x1f525; 系列专栏 &#xff1a; node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 &#x1f525;前言 在文章&#x1f449;Node.js — 前…

React脚手架工具创建项目的详细介绍

文章目录React脚手架工具脚手架工具解析create-react-app创建React项目目录的结构分析从零编写代码React脚手架工具 脚手架工具解析 如果我们只是开发几个小的demo程序&#xff0c;那么永远不需要考虑一些复杂的问题: 比如目录结构如何组织划分; 比如如何管理文件之间的相互依…

Python lxml库的安装和使用

lxml 是 Python 的第三方解析库&#xff0c;完全使用 Python 语言编写&#xff0c;它对 Xpath 表达式提供了良好的支持&#xff0c;因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 安装lxml库 lxml 属于 Python 第三方库&#xff0c;因此需要…

全网多种方式解决Unchecked runtime.lastError: The message port closed before a response was received的错误

文章目录1. 文章引言2. 分析问题3. 解决问题4. 解决该错误的其他方法1. 文章引言 今天启动项目后访问Knife4j接口文档&#xff0c;却报出下图错误&#xff1a; 在报出Knife4j文档请求异常错误时&#xff0c;赶紧打开控制台&#xff0c;如下所示&#xff1a; 即Unchecked runti…