您的位置:首页 > Web前端 > Vue.js

Vue + node.js(Express) 项目中实现换头像与文件上传

2020-01-13 19:51 591 查看

Vue + node.js(Express) 项目中实现换头像与文件上传

实现效果

上传后

// html部分
<div class="head_img">
<img :src="userInfo.avatar"/>
</div>
<div class="setting_right" @click.stop="uploadHeadImg">
<div class="caption">更改头像</div>
</div>
// display: none, 调用uploadHeadImg获取到hiddenInput的dom执行点击事件
<input type="file" accept="image/*" @change="handleFile" class="hiddenInput"/>

因为input file的样式不好改,所以直接display:none了,使用uploadHeaderImg操作DOM( 虽然Vue中不提倡 ), 但是香啊!!!

// Vue实例中
data () {
return {
userInfo: {
avatar: ''
}
}
}
methods: {
uploadHeadImg () {
// 实现隐藏被点击的效果, 这样就可以不用修改input的样式
this.$el.querySelector('.hiddenInput').click()
},
handleFile (e) {
let $target = e.target || e.srcElement
// 获取到上传的file
let file = $target.files[0]
// 创建FileReader的实例用于读取文件
let reader = new FileReader()

// 生成表单格式
let param = new FormData()
// 加入参数字段
param.append('file', file)
param.append('userId', localStorage.getItem('userId'))

// 无法直接查看param,可以用get的方法查看
console.log(param.get('file'))
console.log(param.get('userId'))

// axios请求
axios.post('/api/user/addImg', param, {
// application/x-www-form-urlencoded:默认编码方式
// multipart/form-data: 设置指定传输数据为二进制数据,例如图片、mp3、文件
// text/plain:纯文本的传输。空格转换为“+”,但不支持特殊字符编码。
headers: { 'Content-Type': 'multipart/form-data' }
}).then(res => {
// 后端文件存储完成后再进行图片的读取操作
// 读取file文件作为base64格式
reader.readAsDataURL(file)
})

// 读取成功的操作  ( 更换头像 )
reader.onload = data => {
let res = data.target || data.srcElement
// res.result 为图片的base64格式, 直接放入img标签的src中即可
this.userInfo.avatar = res.result
}
// 读取失败的操作
reader.onerror = (e) => {
console.log('error' + e)
}
}
}
// 安装 multer 模块
npm i multer -S

// 安装 fs 模块
npm i fs -S
// 引入模块
const express = require("express");
router  = express.Router();
const multer = require('multer')
const upload = multer({dest: 'uploads/'})	// 配置图片文件的路径(没有后缀名)
const fs = require('fs')

因为multer模块的上传的图片没有后缀名,无法正常显示

我们可以通过req.file获取到文件的对象参数以及后缀名type,对文件进行拼接处理

// Express中 ( /api/user )
const express = require("express");
router  = express.Router();
const multer = require('multer')	// 引入 multer模块
const upload = multer({dest: 'uploads/'})	// 配置图片文件的路径(没有后缀名)

router.post('/addImg',upload.single('file'), (req, res, next) => {

// 获取到file的信息 ---> 只能通过req.file
let fileObj = req.file

// 获取到body中userId信息
let { userId } = req.body

// 分割出type
let originalArr = fileObj.originalname.split('.')
// 获取到type ( jpg/png/gif )
let type = originalArr[originalArr.length - 1]

// 读取文件 ( path, 'utf-8'(这里不写解码类型,直接把回调函数中的data写入新文件即可), callback)
fs.readFile('uploads/' + fileObj.filename, (err, data) => {
if (err) throw err

// 创建复制图片的路径 以及 拼接type形成一个完整的图片文件
let newPath = '/img/headerImg/' + fileObj.filename + "." + type

// 写入复制的图片 (path, data, callback)
fs.writeFile('public' + newPath, data, (err) => { // 把读取到的data写入
if (err) throw err

// 删除原uploads路径下的图片
fs.unlink('uploads/' + fileObj.filename, () => {
res.send({
code: '200',
msg: '上传成功'
})
})
})
})
})

module.exports = router;

当然在配置multer的路径的时候也可以直接配置需要存放的路径
然后用fs模块来修改文件的格式即可

const multer = require('multer')	// 引入multer模块
const upload = multer({dest: 'public/img/headerImg'}) // 存放的路径

router.post('/addImg',upload.single('file'), (req, res, next) => {

// 获取到file的信息 ---> 只能通过req.file
let fileObj = req.file

// 获取到body中userId信息
let { userId } = req.body

// 分割出type ( jpg/png/gif )
let originalArr = fileObj.originalname.split('.')
let type = originalArr[originalArr.length - 1]

// rename的参数1: 原文件的路径和文件名(没有后缀名无法显示)
// 		 参数2: 修改后的文件路径和文件名(有后缀名可以显示)
// 		 参数3: 回调函数
fs.rename('public/img/headerImg' + fileObj.filename, 'public/img/headerImg' + '.' + type, err => {
if (err) throw err
res.send({
code: '200',
msg: '上传成功'
})
})
})

然后就可以显示啦

当然在项目中后端还需要加入数据库的操作,这里没有在接口中写出来

把服务器中的路径存入数据库中,随后每次读取数据库中的路径放入src中就可以实现完整的效果了

  • 点赞
  • 收藏
  • 分享
  • 文章举报
Nicis丶 发布了8 篇原创文章 · 获赞 4 · 访问量 457 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: