リッチ テキストを使用する場合、ほとんどのテキストには画像が保存されますが、ページがエコーされたときに大きな画像をプレビューする機能を使用することもあります。ここでは、element-ui に付属する ImagePreview コンポーネントを使用して実装します。img 要素は v-html によってレンダリングされるため、クリック イベントをそれにバインドすることも、ImagePreview コンポーネントを直接使用することもできません。この機能を達成するために小さな変更を加えます。
ここでは ImagePreview v-show が false に設定されており、ここではコンポーネントのプレビュー ページのみが使用され、画像表示では v-html を使用して画像をレンダリングします。
<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要素ではクリックイベントを設定できないため、親要素のクリックイベントをバインドすることができます、クリック イベントに従って、実際にクリックされた要素を取得します。
イベントの代表団
イベント委任は、イベント フローの特性を使用して開発要件の一部を解決するナレッジ スキルです。
利点: 登録数が減り、プログラムのパフォーマンスが向上します。
原則: イベント委任は実際にイベントバブリングの特性を利用しています。
親要素のイベントを登録します。子要素をトリガーすると、子要素が親要素にバブルアップし、それによって親要素のイベント実装がトリガーされます。event object.target.tagName は、実際にイベントをトリガーする要素を取得できます。
//显示大图
replayImgShow(e){
this.previewSrc='';
if(e.target.tagName=='IMG'){
this.previewSrc=e.target.currentSrc;
let obj=this.$refs.imagePreview;
//调用组件自定义方法,模拟组件点击事件
obj.click()
}
},
2. 画像スタイルを設定する
/* v-html渲染的元素样式,用/deep/才会生效 */
.log-text-class /deep/ img {
//设置富文本图片宽高
width: 50%;
height: 50%;
}
3. ImagePreview コンポーネントの変更
ImagePreview コンポーネントへの変更 (ImagePreview コンポーネントの要素 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;
},