工作中遇到了一个问题,须要对接口返回的数据进行解决。
接口返回的:<img src="http://www.test.com/1.png" ... /> 你好 <img src="http://www.test.com/2.png" ... /> 你好,你好
理论须要的:
<ImgMsg url="http://www.test.com/1.png" /> 你好 <ImgMsg url="http://www.test.com/2.png" /> 你好,你好
思考后,想到了一种形式,借助 component
,将 img 替换为本人封装的 ImgMsg 组件(蕴含了占位图、算出最佳适合显示比例、预览性能等性能)。
具体实现须要进行如下步骤:
1. 配置项
// vue.config.js
module.exports = {
...
/* 是否应用蕴含运行时编译器的 Vue 构建版本。设置为 true 后你就能够在 Vue 组件中应用 template 选项了,然而这会让你的利用额定减少 10kb 左右。(默认 false) */
runtimeCompiler: true,
}
2. 全局注册
// components/Common/index.js
import Vue from 'vue'
imoort ImgMsg from '@/components/ImgMsg'
const components = [ImgMsg];
components.forEach(component => {Vue.component(component.name, component);
});
3. 组件中应用
<!-- MassMsg.vue -->
<template>
<div>
<component :is="massMsg"></component>
</div>
</template>
<script>
export default {
name: 'massMsg',
data() {
return {regImg: /<img((?!class="biaoqing").)*?>/gi,
regDataSrc: /data-src="(.*?)"/,
};
},
props: {
item: {
type: Object,
default: () => {}
}
},
computed: {massMsg() {
const msg = this.item.content.replace(this.regImg, result => {let groups = this.regDataSrc.exec(result);
if (groups) {return '<ImgMsg url="' + groups[1] + '"></ImgMsg>';
}
return result;
});
return {template: `<div>${msg}</div>`
};
}
}
};
</script>
附:
ImgMsg 组件代码
<!-- ImgMsg.vue -->
<template>
<img class="el-common-img" :src="imgSrc" @click="setPicPreviewVisible(url)" @load="loadImg($event, url)" @error="loadError" />
</template>
<script>
import M from '@store/mutations';
import imgLoading from '@assets/images/loading.gif';
import loadError from '@assets/images/loadError.png';
export default {
name: 'imgMsg',
data() {
return {
ImgMaxWidth: 170,
ImgMaxHeight: 170,
imgSrc: imgLoading
};
},
props: {
url: {
type: String,
default: ''
}
},
watch: {url(newVal) {if (newVal) this.imgSrc = newVal;
}
},
methods: {
/**
* 解决图片音讯显示大小
*/
loadImg(e, url) {
let imgTarget = e.target,
img = document.createElement('img');
img.onload = e => {
let target = e.target;
let {w, h} = this.getImgSize(this.ImgMaxWidth, this.ImgMaxHeight, target.width, target.height);
imgTarget.width = w;
imgTarget.height = h;
this.imgSrc = url;
};
img.src = url || '';
},
getImgSize(mw, mh, w, h) {if (w > mw && h <= mh) {
// 图片宽度大于最大值
h *= mw / w;
w = mw;
} else if (w <= mw && h > mh) {
// 图片宽度小于等于最大值
w *= mh / h;
h = mh;
} else if (w > mw && h > mh) {
// 图片宽度和高度均大于最大值
if (w / h >= mw / mh) {
// 宽高比大于默认比例
h *= mw / w;
w = mw;
} else {
// 宽高比小于等于默认比例
w *= mh / h;
h = mh;
}
}
return {w, h};
},
/**
* 预览图片
*/
setPicPreviewVisible(url) {this.$store.commit(M.Chat.setPicPreviewVisible, true);
this.$store.commit(M.Chat.setPicPreviewSrc, url);
},
/**
* 加载谬误占位图片
*/
loadError() {this.imgSrc = loadError;}
}
};
</script>