先看效果图:
上面展示了两张从本地添加的准备上传服务器的预览图片,效果还不错吧,哈哈哈。
下面是该页面中紫色框的布局与实现代码,我想有些人也不喜欢HTML中默认的上传文件样式,实在辣眼睛:
<template>
<div class="uploadFile">
<!-- ul、li标签用于展示从本地添加的预览图片 -->
<ul v-show="uploadImg.length!=0">
<li v-for="(item,index) in uploadImg"
:key="index"
class="addPic">
<img :src="item">
</li>
</ul>
<input type="file"
id="file"
accept="image/*"
@change="getPicture($event)">
<button @click="callFile"
v-show="showInputImg">+</button>
</div>
</template>
<script>
export default {
data(){
return {
uploadImg:[]
}
},
computed: {
showInputImg () {
return this.uploadImg.length < 3;
}
},
methods: {
getPicture (e) {
//预览图片
let src = window.URL.createObjectURL(e.target.files[0]);
this.uploadImg.push(src);
//将图片文件转化成base64格式图片
var reader = new FileReader();
reader.onload = (e) => {
//e.target.result 就是从本地读取的图片的base64格式,将它上传给服务器即可
//使用axios的post方法上传即可
}
reader.readAsDataURL(e.target.files[0])
},
callFile () {
//点击添加图片按钮,触发type:"file"的input标签
let fileDom = document.querySelector("#file")
fileDom.click()
}
}
}
</script>
<style scoped>
input {
/* 隐藏默认的"打开文件"样式 */
display: none;
}
.uploadFile {
display: flex;
height: 120px;
line-height: 120px;
padding: 10px 0;
border-bottom: 1px solid rgb(235, 235, 235);
overflow: hidden;
}
.uploadFile ul {
display: flex;
}
.uploadFile ul li {
margin-right: 10px;
}
.uploadFile .addPic img {
height: 100px;
width: 100px;
}
.uploadFile button {
height: 100px;
width: 100px;
font-size: 50px;
border: 1px dashed rgb(182, 182, 182);
color: rgb(182, 182, 182);
background-color: rgb(243, 243, 243);
}
</style>
上面是紫色框中完整的代码。
HTML分析:
- ul、li 标签是用于展示从本地选中的图片的,uploadImg数组是用于存放选中的图片的
"临时"
URL,若uploadImg.length==0表明没有选中本地图片,则此时ul、li标签不展示。 - 当type="file"的input标签是用于打开本地文件的,它有个默认样式,但在css中我们将它设置为不展示,即display:none.
- button标签就是紫色框中的带有+号的选择图片的方框按钮,它触发打开本地文件界面。button的v-show绑定了一个计算属性控制着该按钮的显示,因为我只想让它最多添加三张图片,当有三张图片后,就不再展示这个按钮,自然就实现了最多添加三张图片。
JS分析:
- callFile()被按钮的点击事件绑定,当点击按钮它就调用input标签的click事件,因为为了更美观的样式,input被我们设置为不可见,那么我们只能通过按钮点击去调用input的click事件,从而打开本地文件界面。
- input标签的change事件绑定了getPicture()函数,即当用户点击选中某张图片,那么就会触发change事件。参数$event带有选中图片相关的信息。可以通过console.log(e.target.files)查看选中文件的信息。为什么我们使用
e.target.files[0]
呢?因为我这里实现的是选中单张图片,因此files数组中的0下标就是我们选中的图片信息。 - 为了预览图片,我们需要生成一个URL,即使用
window.URL.createObjectURL(e.target.files[0])
,注意:这个URL是临时URL,不是服务器返回的图片URL,当我们关闭网页,该URL就会失效,因此用来预览图片非常合适。 - FileReader是文件读取函数,
reader.readAsDataURL(e.target.files[0])
这是同步读取文件,参数就是图片的相关信息,当图片读取完毕之后就会触发reader.onload
,进而执行它的回调函数,注意这里的回调函数最好使用箭头函数,因为箭头函数不改变this指针的指向,此时this还是指向vue组件实例,如果是function(){}则this.指向这个文件对象。