创作灵感
最近在写项目时,遇到了上传头像的需求,我使用的是element组件中的upload组件。但是在使用时,我需要实现预览、手动上传头像等功能。然而在使用饿了么组件时,这些功能还是需要我们自己去手动实现的,在手动实现的时候,大家可能会遇到一些问题,下面我就向大家分享一下我是如何实现的。
关闭自动上传
要想实现手动上传,我们就需要关闭el-upload组件的自动上传。首先,先向大家分享该组件的官方解释文档地址:Upload 上传 | Element Plus
关闭自动上传的方法为,将其中的auto-upload设置为false即可。需要注意的是,我们需要在auto-upload前加上一个:,既变为:auto-upload="false"。不加:会将后面的识别为字符串。
获取上传组件的值
关闭自动上传以后,我们就需要手动拿到用户选取的头像,并在获取的时候,做到以下两件事:
1、将获取的值保存下来,用户提交时再发送给后端。
2、将获取的值进行展示。
我们可以注意到,el-upload组件有着多个钩子函数,我们应当根据自己的需求进行选取。这里我使用的是on-change钩子函数,也就是当选取的图片发生改变时,会促发该函数。
值得注意的是,因为我们关闭了自动上传,所以有许多钩子函数我们是不能使用的。例如on-success、on-error、on-progress等等函数都是不能再用了,因为我们不会自动上传,也就不会触发对应的钩子函数。因此,这里我使用的是on-change钩子函数,这个函数在添加文件时会被触发,和自动上传无关。
我们的大致思路是,用户选取了新的头像——》将新的头像保存下来,并进行预览展示。然而,当我们在on-change所绑定的函数内部改变新的头像值时,却发现并不能生效。上网查询了相关博客,发现这是因为该钩子函数只用于处理一些上传图片的逻辑,不能改变页面内的值。这也就意味着,我们不能直接在该函数内部修改页面内的值,解决办法是——在该函数内部调用其他的函数进行值的修改。具体实现如下:
//用户选择了头像
function selectNewAvatar(e){//此钩子函数不能直接修改页面内的值,调用其他函数修改
avatarChange(e.raw)
}
//更改头像的值
function avatarChange(e){
avatar.value=e
var reader = new FileReader();
reader.readAsDataURL(e);
reader.onload=function(event){
avatar_url.value=event.target.result
}
}
可以看到,用户选择头像时调用一个钩子函数 ,但其值的修改并不在这个函数内部进行,而是通过调用另外一个函数来修改页面内对应的值。
同时,大家可以发现,实现图片预览的功能也在该函数中实现,具体为使用了一个FileReader对象来实现。其中e为对应的图片对象。这里值得注意的是,我们不能直接使用el-upload所获取的对象,而应该使用其中的raw属性。这里应该是饿了么组件对该对象进行了一些包装。
下面再给大家看一下html应该如何书写,如下:
<el-upload
class="new-avatar-upload"
:auto-upload="false"
:limit="1"
:on-change="selectNewAvatar"
:show-file-list="false"
>
<img v-if="avatar_url" :src="avatar_url" class="new-avatar-upload-img"/>
<el-icon v-else class="new-avatar-upload-icon"><Plus /></el-icon>
</el-upload>
在html内,图片的预览就靠img中的src属性完成就可以了。
在上述代码内,您可能会发现,你选取一次头像以后,再次选取就无效了。这可能是你的最大上传限制数量为1,这样你的就不能再向内部添加新的文件了,也就不能触发on-change钩子函数了。你只需要将限制的数量设置大一些就好了,因为是手动上传,最后你手动上传最新的一张头像即可。
总结
在使用饿了么的上传组件实现图片预览时,最容易出错的地方就算钩子函数内部不能修改页面内的值。要是你不懂这一个点,很可能一直都是无用功。
最后实现的效果大致如下:
其中,左边的是之前的头像,右边就是你所选择的新的头像,并且可以展示出来了。