做项目的时候遇到一个功能,点击选择封面图片,上传图片的功能,取消显示回选择封面图片。
查阅一些资料后,发现主要还是使用到css样式来完成。
该代码是vue2+element-ui的代码,只用于展示思路,请勿盲目copy
代码如下:
方法一:使用readAsDataURL,转化成base64
(注意:img标签的src只能接收base64,绝对路径,相对路径,不支持其他的!!)
html代码:
<el-form-item label="文章图片" prop="cover_Img">
<div class="articleImg">
<img src="@/assets/images/cover.jpg" alt=""
v-if="!this.articleForm.cover_Img">
<img :src="cover_Img" alt="" v-else>
<input type="file" name="" id="" accept="image/*,.pdf" @change="changeFn" />
</div>
</el-form-item>
思路:一张图片,一个input框(type="file"),将input大小设置为和图片同等大小,然后使用
opacity: 0;将input标签透明化,使用定位,input定位在图片相同位置。这样样式这块就基本完成
css代码:
.articleImg {
position: relative;
width: 400px;
height: 280px;
img {
width: 400px;
height: 280px;
}
input {
position: absolute;
opacity: 0;
top: 0;
left: 0;
width: 400px;
line-height: 280px;
}
}
js代码:
changeFn(e){
// 在input标签内@change = changeFn, 监听change事件
// e.target.files 获取到选择的文件,也就是图片 e.target.files[0]就是你选择的图片的信息
if (e.target.files.length === 0) {
// 没有选择任何
this.articleForm.cover_Img = ''
} else {
//用户操作并选中,则应该让图片显示在页面上
// 这里用到FileReader 对象,
//他允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容
// 构造器创建一个新的对象fr
const fr = new FileReader()
//fr将图片转化成base64格式
fr.readAsDataURL(e.target.files[0])
// 页面加载完毕,将转化的base64传入cover_img
fr.onload = e => {
this.articleForm.cover_Img = e.target.result
}
}
方法二: 使用URL.ctreateObjectURL来完成
createObjectURL
返回一段带hash的url,并且一直存储在内存中,直到document触发了unload
事件(例如:document close)或者执行revokeObjectURL
来释放。- 使用
createObjectURL
可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存 - 大家可以看一下掘金的这篇文章!!!
- 上面两条引用自URL.createObjectURL讲解 - 掘金
只用一个标签来完成功能:
html代码:
<el-form-item label="文章图片" prop="cover_Img">
<div class="articleImg">
<img src="../../assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef" />
<input type="file" name="" id="" accept="image/*,.pdf" @change="changeFn" />
</div>
</el-form-item>
js代码
import coverImg from '@/assets/images/cover.jpg'
export default{
//...... 此处省略
methods{
changeFn(){
const files = e.target.files
if (e.target.files.length === 0) {
// 没有选择任何
this.articleForm.cover_Img = ''
// 标签里面可以写路径,css也可以,但是js里不能写路径,webpack打包时会把他当成了字符串解析!!!!
// 通过setAtrribute方法来设置其属性
this.$refs.imgRef.setAttribute('src', coverImg)
} else {
this.articleForm.cover_Img = files[0]
const url = URL.createObjectURL(files[0])
this.$refs.imgRef.setAttribute('src', url)
}
}
}
}
思路同上:帅哥美女帮忙点个赞,点个关注,会持续更新的,感谢!!!跪谢(显然,这句才是重点啊,图穷匕见了)
上面两种方法,第二种方法性能要个更好一些,所以个人更推荐第二种方法!!
原因如下:
URL.ctreateObjectURL可以节省性能,而且更快(同步代码),
readAsDataURL属于异步,FileReader.readAsDataURL(file)可以获取一段data:base64的字符串,会消耗一些内存。