Vue.js 原生 FormData 实现无刷新图片上传

作者:模板散步时间:2026-10-22 06:51:10浏览:133

本文介绍如何在 Vue.js 中利用原生 JavaScript API 和 FormData 对象,通过 AJAX 方式实现无刷新图片上传。文章涵盖前端文件选择、预览及提交逻辑,并结合 Node.js 与 formidable 库演示后端接收与保存文件的完整流程,提供前后端分离架构下的实用代码示例。

Vue.js 无刷新图片上传概述

对于许多 Vue.js 开发者而言,通过 AJAX 上传图片是一项常见需求。在前后端分离的开发模式下,我们倾向于使用 AJAX 处理数据交互,因为传统的表单提交会导致页面刷新或跳转,而 AJAX 则能实现图片等文件的无刷新上传。

虽然市面上已有封装好的 npm 包,但直接使用原生 JavaScript API 实现同样简洁,且具备更高的灵活性。在可能的情况下,优先使用原生 API 是更佳选择。以下将通过一个头像上传的简单案例来演示具体实现方法。

效果图

Vue.js 无刷新图片上传概述

前端代码实现与逻辑解析

前端实现


<template>
 <div class="admin">
 <div class="admin-content">
  <div class="edit">
  <div class="avatar">
   <div class="img">
   <img :src="avatar" @click="setAvatar">
   <span>更改</span>
   </div>
   <input type="file" name="avatar" accept="image/gif,image/jpeg,image/jpg,image/png" style="display:none" @change="changeImage($event)" ref="avatarInput">
  </div>
  <button type="button" @click="edit">确认修改</button>
  </div>
 </div>
 </div>
</template>
<script>
export default {
 data() {
 return {
  avatar: this.$store.state.administrator.avatar,
 }
 },
 methods: {
 edit() {
  // 修改了头像
  if (this.$refs.avatarInput.files.length !== 0) {
   var image = new FormData()
   image.append('avatar', this.$refs.avatarInput.files[0])
   this.axios.post('/avatar', image, {
   headers: {
    "Content-Type": "multipart/form-data"
   }
   })
  }
  }) 
 },
 setAvatar() {
  this.$refs.avatarInput.click()
 },
 changeImage(e) {
  var file = e.target.files[0]
  var reader = new FileReader()
  var that = this
  reader.readAsDataURL(file)
  reader.onload = function(e) {
  that.avatar = this.result
  }
 }
 }
}
</script>

上述代码的逻辑如下:点击头像区域会触发 setAvatar 函数,该函数进而触发隐藏的 input 元素的 click 事件,从而弹出文件选择对话框。用户选择图片后,触发 changeImage 函数,该函数负责预览所选图片。最后,点击“修改”按钮时,将选定的资源发送至后端服务器。

后端 Node.js 接收与保存处理

后端处理

后端接收到上传的资源后,需将其保存至服务器。此处以 Node.js 为例,使用 formidable 库来解析上传的数据。


exports.avatar = function(req, res, next) {
 let form = new formidable.IncomingForm()
 form.parse(req, function(err, fields, files) {
 if (err) {
  return res.json({
  "code": 500,
  "message": "内部服务器错误"
  })
 }

 // 获取后缀名
 let extname = path.extname(files.avatar.name)
 let oldpath = files.avatar.path;
 let newpath = './public/avatar' + extname;
 let avatarName = 'avatar' + extname;
 // 更改名字和路径
 fs.rename(oldpath, newpath, function(err) {
  if (err) {
  return res.json({
   "code": 401,
   "message": "图片上传失败"
  })
  }
 })
 // 更新数据库
 db.updateMany('users', { "user": username }, { "avatar": avatarName },
  function(err, result) {
  if (err) {
   return res.json({
   "code": 401,
   "message": "头像更新失败"
   })
  }
  return res.json({
   "code":200,
   "message": "头像上传成功"
  })
  })
 })
}

后端解析 AJAX 提交数据的方法与传统表单提交类似。对于前端开发者而言,若不熟悉后端代码,理解前端逻辑即可。此处提供一个 Demo 项目:https://github.com/wmui/vueblog,该后台项目包含头像修改功能,采用 AJAX 上传图片,核心代码不足百行,实现了前后端分离。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章