1.点击图片-模拟文件选择框点击事件
(1)添加文件选择框
按钮区域中,新增 <input type = "file" />
(定义文件选择字段和 "浏览..." 按钮,供文件上传)
(2) 首先给选择图片 按钮注册点击事件绑定处理函数 @click="chooseImg"
(3)在事件处理函数 模拟点击文件选择框
在methods 中声明 chooseImg 函数
// 模拟点击行为
this.$refs.iptRef.click()
2.通过change事件获取选中的图片
(1)给文件选择框绑定change事件
@change="onFileChange"
(当元素的值改变时发生 change 事件(仅适用于表单字段))
(2)在methods中声明onFileChange函数
通过e事件对象获取选择文件列表
根据files伪数组的长度判断是否选择了图片
3.渲染用户选择的头像
-
使用FileReader将图片转化为base64的字符串并存储到data变量中
-
实现用户预览头像的渲染
-
动态控制“上传头像”按钮的禁用状态
-
基于 FileReader 把文件读取为 base64 的字符串:
-
使用v-if
和v-else
指令,动态预览用户头像: -
基于属性绑定指令,动态控制“上传头像”按钮的禁用状态:
4.实现更换头像的功能
-
上传头像按钮注册点击事件绑定处理函数
-
发送请求实现图片上传
<template>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>更换头像</span>
</div>
<div>
<!-- 图片,用来展示用户选择的头像 -->
<img :src="avatar" alt="" class="preview" v-if="avatar" />
<img
src="../../../assets/images/avatar.jpg"
alt=""
class="preview"
v-else
/>
<!-- 按钮区域 -->
<div class="btn-box">
<input
type="file"
accept="image/*"
style="display: none"
ref="iptRef"
@change="onFileChange"
/>
<el-button
type="primary"
icon="el-icon-plus"
@click="$refs.iptRef.click()"
>选择图片</el-button
>
<el-button
type="success"
icon="el-icon-upload"
:disabled="avatar === ''"
@click="uploadAvatar"
>上传头像</el-button
>
</div>
</div>
</el-card>
</template>
<script>
export default {
name: 'UserAvatar',
data() {
return {
avatar: ''
}
},
methods: {
//上传用户头像
async uploadAvatar() {
const { data: res } = await this.$http.patch('/my/update/avatar', {
avatar: this.avatar
})
if (res.code !== 0) return this.$message.error(res.message)
this.$message.success(res.message)
// 清空
this.avatar = ''
this.$store.dispatch('initUserInfo')
},
onFileChange(e) {
// 1.获取用户选择的文件列表(伪数组)
const fileList = e.target.files
console.log(fileList)
// 2.判断有没有选中图片
if (fileList.length !== 0) {
// 3.选择了图片
// 3.1 创建fileReader对象
// 将图片转换为base64的字符串 FileReader
const reader = new FileReader()
//3.2 将文件对象的数据读取到reader中,转换为base64的字符串
reader.readAsDataURL(fileList[0])
// 3.3 监听 load事件,读取完成触发回调函数
reader.addEventListener('load', () => {
// 3.4获取到base64字符串,存储到data中
this.avatar = reader.result
})
} else {
// 4.没有选择了图片
this.avatar = ' '
}
}
/* chooseImg() {
// 模拟点击行为
this.$refs.iptRef.click()
} */
}
}
</script>
<style lang="less" scoped>
.btn-box {
margin-top: 10px;
}
.preview {
object-fit: cover;
width: 350px;
height: 350px;
}
</style>