持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
更换用户图片在vue项目中是非常常见的,该篇文章带来的是前端篇
项目实现
API
在api/index.js下新建更换头像的API
// 更新用户头像
export const UpdateAvatarAPI = data =>
axios({
url: '/my/update_avatar', // 路径
method: 'POST', // 请求方式
headers: { // 请求头
'Content-Type': 'multipart/form-data'
},
data // 请求体
})
html
- 由于原生更换头像input样式比较丑,且比较难改
- 一般都是自己写一个div样式,再隐藏原生的
- 当点击div时,用js中的click()方法点击原生input
<div class="item" @click="clickAvatarFn">
<input type="file" v-show="false" ref="iptAvatarRef" @input="editAvatarFn">
<span>头像</span>
<div class="item-content"><img :src="userinfo.user_pic" alt=""></div>
<van-icon name="arrow" />
</div>
script
- 图片的上传,一般都是以表单元素上传
- FormData对象,就是用于异步上传二进制文件
- e.target.files 是个数组, 长度大于0时代表用户选中了图片,反之用户没有选择图片
// 点击头像
clickAvatarFn () {
this.$refs.iptAvatarRef.click() // 通过ref拿到input节点
},
// 编辑头像
async editAvatarFn (e) {
const file = e.target.files // e.target.files 是个数组
if (file.length > 0) { // file.length > 0代表选了图片,反之就是没选图片
const fd = new FormData() // 表单元素
fd.append('avatar', file[0]) // file[0] 文件对象, 'avatar' 是key名
const { data: res } = await UpdateAvatarAPI(fd)
if (res.status !== 200) return this.$notify({ type: 'danger', message: res.message }) // res.status判断头像是否上传成功
this.$notify({ type: 'success', message: '更新图片成功' }) // this.$notify是vant组件库中的消息通知组件
const { data: res1 } = await getMyInfoAPI() // getMyInfoAPI获取用户信息的API,用于刷新页面
this.$store.commit('qq/UpdateUserInfo', res1.data) // 将最新值提交的vuex中
}
}
前端预览图片的两种方式
- 使用方式一的createObjectURL可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存
- 如果不太在意设备性能问题,并想获取图片的base64,则推荐方式二FileReader.readAsDataUR
方式一
- createObjectURL是同步执行
- 这种方式只能在本机使用
- file[0]是文件对象,因为上面已经写了,所以就不再写判断了
const avatar = URL.createObjectURL(file[0]) // 临时地址,只能在本机使用
方式二
- FileReader.readAsDataURL是异步执行
- avatar结果是一个base64格式的图片,所以不局限于本机,其他地方也可以使用
const fr = new FileReader()
fr.readAsDataURL(file[0]) // file[0]文件对象
fr.onload = e => { // onload等待把文件读成base64字符串后会触发onload事件函数
const avatar = e.target.result // e.target.result的值就是读完的结果
}