我们在使用富文本的时候,大多数都会将图片存储,在页面回显的时候,有时候会用到预览大图的功能。这里利用element-ui自带的ImagePreview组件进行实现,由于img元素是v-html渲染的,我们无法为其绑定点击事件,也无法直接用到ImagePreview组件,所以我们需要进行一些小改动来实现这个功能。
这里将ImagePreview v-show设置为false,这里只用到组件的预览大图页面,图片的显示用v-html渲染img,
<div v-html="logText" class="log-text-class" @click="replayImgShow($event)"></div>
<ImagePreview :src="previewSrc" ref="imagePreview" v-show="false"></ImagePreview>
data() {
return {
//图片预览src
previewSrc:'',
//富文本html
logText:''
}
}
1、绑定点击事件
这里利用了js的事件委托,. log-text-class的div是img的父元素,由于v-html渲染的img元素我们无法设置点击事件,可以通过绑定父元素的点击事件,然后根据点击事件来获取真正点击的元素。
事件委托
事件委托是利用事件流的特征解决了一些开发需求的知识技巧
- 优点:减少注册次数,可以提高程序性能
- 原理:事件委托其实是利用事件冒泡的特点
- 给父元素注册事件,当我们触发子元素时,会冒泡到父元素身上,从而触发父元素的事件 实现:事件对象.target.tagName可以获得真正触发事件的元素
//显示大图
replayImgShow(e){
this.previewSrc='';
if(e.target.tagName=='IMG'){
this.previewSrc=e.target.currentSrc;
let obj=this.$refs.imagePreview;
//调用组件自定义方法,模拟组件点击事件
obj.click()
}
},
2、设置img样式
/* v-html渲染的元素样式,用/deep/才会生效 */
.log-text-class /deep/ img {
//设置富文本图片宽高
width: 50%;
height: 50%;
}
3、ImagePreview组件改动
ImagePreview组件改动(ImagePreview组件elements-ui自带的图片预览组件)
1、el-image添加ref,便于后续获取元素模拟点击事件
<template>
<el-image
//这里添加ref
ref="image"
:src="`${realSrc}`"
fit="cover"
:style="`width:${realWidth};height:${realHeight};`"
:preview-src-list="realSrcList"
>
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
2、添加自定义click()方法
methods:{
click(){
//显示预览大图
this.$refs.image.showViewer = true
//模拟点击事件,触发查看大图功能
this.$refs.image.clickHandler()
}
}
4、存在问题
由于富文本输入框支持图片的复制粘贴,复制粘贴的图片,并非以url的形式存储在富文本html中,而是由base64格式存储的,在预览的时候会导致图片打不开,
解决方案:
//显示大图
replayImgShow(e){
this.previewSrc='';
if(e.target.tagName=='IMG'){
let str=e.target.currentSrc;
let str1=str.split(",");
/*复制粘贴的图片是已base64图片存储的,需要特殊处理*/
if (str1[0]==="data:image/png;base64"){
this.previewSrc="base64:"+str1[1];
}else {
this.previewSrc=str;
}
let obj=this.$refs.imagePreview;
obj.click()
}
},
ImagePreview组件改动 添加
if (item.substring(0,7)==="base64:"){
return srcList.push("data:image/png;base64,"+item.substring(7));
}
realSrcList() {
if (!this.src) {
return;
}
let real_src_list = this.src.split(",");
let srcList = [];
real_src_list.forEach(item => {
/*复制粘贴的图片是已base64图片存储的,需要特殊处理*/
if (item.substring(0,7)==="base64:"){
return srcList.push("data:image/png;base64,"+item.substring(7));
}
if (isExternal(item)) {
return srcList.push(item);
}
return srcList.push(process.env.VUE_APP_BASE_API + item);
});
return srcList;
},