Vue + ElementUI + ExpressJS实现上传头像的功能
程序员文章站
2022-05-01 21:51:13
...
前端代码
1. 首先我们需要用到elementUI的upload组件
<el-upload
class="avatar-uploader"
:show-file-list="false"
:http-request='uploadAvatar'
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
- http-request钩子函数:可以覆盖默认的上传行为,可以自定义上传的实现。
- brfore-upload钩子函数:在文件上传前进行操作,比如判断是否符合要求。
2. 实现brfore-upload钩子函数
beforeAvatarUpload(file) {
this.file = file
this.fileName = file.name
this.fileType = file.type
const isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
this.$message.error('上传头像图片只能是 JPG | PNG | GIF 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isImage && isLt2M;
},
- 如上图代码所示,我们规定了只能是三种格式,并且大小不能超过2MB
3. 实现http-reuqest钩子函数
uploadAvatar() {
// 使用formData进行文件上传
let formData = new FormData()
formData.append('fileName', this.fileName) // 文件名字
formData.append('file', this.file) // 当前文件
formData.append('name', this.$store.getters.userInfo.name) // 当前登录的用户的名字
formData.append('staff_num', this.getStaffNum) // 当前登录用户的员工编号,在数据库查找时会用到
formData.append('host', `//${window.location.hostname}:5000`) // 把当前主机名传过去,后端利于拼接并且存放在数据库
let url = 'http://localhost:5000/api/avatar/uploadAvatar'
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
let res = JSON.parse(xhr.responseText)
this.$message.success(`${res.data.msg}`)
let dominName = window.location.hostname
this.getUser.avatar = `//${dominName}:5000${res.data.fileUrl}` // 这一步的目的是把vuex里存放的avatar的值也改变
let user = this.getUser
this.$store.dispatch('setUserInfo', user) // 更新vuex
setTimeout(() => {
location.reload() // 300ms之后,刷新页面。否则上传图像之后它不会自动改变
}, 300)
}
}
xhr.open('post', url)
xhr.setRequestHeader('Authorization', localStorage.jwtToken) // 由于后端使用了jwt验证。所以这里要设置一下请求头
xhr.send(formData)
总结一下:文件上传必须使用formData。请求方法可以用jQuery的ajax,也可以使用xmlHttpRequest。本文使用的就是xmlHttpRequest
后端代码
4. 安装forimidable来解析上传的文件
npm i forimidable --save
这时可能有同学会问,什么是forimidable?
formidable : Node.js模块,用于解析表单数据,特别是文件上传。
5. 解析图片
let form = new forimidable.IncomingForm()
form.uploadDir = path.join(__dirname, '../../public/avatars') // 设置静态资源路径
form.keepExtensions = true // 使用源文件的扩展名
form.parse(req, (err, fields, files) => {
if (err) return res.json(err)
let extName = '' // 文件后缀
switch(files.file.type) { // 这一步的目的是设置文件后缀
case 'image/jepg':
extName = 'jpg'
break
case 'image/png':
extName = 'png'
break
case 'image/gif':
extName = 'gif'
break
default:
extName = 'jpg'
break
}
let avatarName = `${fields.name}'s_avatar.${extName}` // 根据传过来的用户名以及上面获取到的后缀名拼接出新的头像的名字
let newPath = form.uploadDir + '/' + avatarName // 获取头像的路径
fs.rename(files.file.path, newPath, (err) => {
// 这一步是重命名,files.file.path是原始文件路径,newPath是上方拼接出来的。
// 同时,重命名还可以避免同一用户上传多个文件。占用服务器资源。
if (err) return res.json({data: {code: 400, msg: '操作失败'}})
// 接下来是将图片地址更新到数据库~
let update = {
avatar: `${fields.host}/avatars/${avatarName}`
}
// 把图片地址更新到数据库
User.findOneAndUpdate({name: fields.name, staff_num: fields.staff_num},
{$set: update}, {new: true}).then(user => {
res.json({data: {
code: 200,
msg: '操作成功',
}})
}).catch(err => res.json({data: {code: 500, msg: 'something error!'}}))
})
})
tips:将头像地址存放到数据库仅仅是更新一下。前端使用的还是更新的vuex里面的数据。 如图 ↓
如果要部署到服务器怎么办?
服务器一般监听80端口,所以拼接地址的时候就不需要 ‘:5000’ 了
以上就是简单的实现上传头像功能。谢谢翻看~
上一篇: 在戴尔游匣7559上安装win10和Ubuntu16.04双系统
下一篇: twisted 18.7.0 requires PyHamcrest>=1.9.0, which is not installed.
推荐阅读
-
VUE + UEditor 单图片跨域上传功能的实现方法
-
vue.js 图片上传并预览及图片更换功能的实现代码
-
node+vue实现用户注册和头像上传的实例代码
-
基于Vue+elementUI实现动态表单的校验功能(根据条件动态切换校验格式)
-
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
-
vue.js实现的全选与全不选功能示例【基于elementui】
-
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
-
cropper js基于vue的图片裁剪上传功能的实现代码
-
vue中element 上传功能的实现思路
-
Vue实现带进度条的文件拖动上传功能