选择的图片文件,要给到img标签上纯前端的预览 让用户更近一步看到自己选择的头像
因为img的标签的src的值只能是以下两个
1、只能是图片的“链接地址”(外链http://开头,图片文件相对路径)(不能发给后台)因为第一种转成http是存在js里的内存里的
2、是图片的base64字符串(而且字符串还必须是data:image/png;base64,图片转base64字符)(可以传给后台)
所以在用户点击上传图片的时候我们需要把上传的图片转成以上两种形式的任意一种。
<template><el-card class="box-card"><div slot="header" class="clearfix"><span>更换头像</span></div><div><!-- 图片,用来展示用户选择的头像 --><imgv-if="!this.avatar"class="the_img"src="../../assets/images/avatar.jpg"alt=""/><img v-else class="the_img" :src="this.avatar" alt="" /><!-- 按钮区域 --><div class="btn-box"><inputtype="file"accept="image/*"style="display: none"ref="iptRef"@change="onFileChange"/><el-button type="primary" icon="el-icon-plus" @click="chooseImg">选择图片</el-button><el-buttontype="success"icon="el-icon-upload":disabled="avatar === ''">上传头像</el-button></div></div></el-card>
</template><script>
export default {name: 'UserAvatar',data () {return {avatar: ''}},methods: {// 选择图片->点击事件chooseImg () {// 目的:为了让input[type=file]标签,让他再用js代码来触发它的点击事件(导致它默认行为给一个文件选择窗口)// 原因:input[type=file]它是原生标签,样式不太好改// 解决:移花接木this.$refs.iptRef.click()},// 选择图片确定了onFileChange (e) {// e原生事件对象const files = e.target.files // 拿到用户选择的文件数组if (files.length === 0) {// 证明刚刚文件选择窗口打开了,但时它一个文件都没选择点击了确定关闭选择弹窗} else {// 证明它选择了文件(默认只能选择一个,如果选择多个你需要给input标签加额外原生属性)// 解决方案1:文件->内存临时地址(这个地址只能在js里内存里不能发给后台)// 语法:URL.createObjectURL(上传图片的文件对象)// 返回值:内存临时地址// this.avatar = URL.createObjectURL(files[0])// 解决方案2:文件->base64字符串(此字符串是可以发给后台的)const fr = new FileReader()fr.readAsDataURL(files[0]) // 传入文件对象开始读fr.onload = (e) => {// onload等待把文件都城base64字符串后会触发onload事件函数// e.target.result的值就是读完的结果this.avatar = e.target.result}}}}
}
</script><style lang="less" scoped>
.btn-box {margin-top: 10px;
}
.preview {object-fit: cover;
}
.the_img {width: 350px;height: 350px;
}
</style>
展示: