[vue]对"将图片原地替换为它的缩略图"自定义指令的改进
上一篇文章的自定义指令非常简陋,使用场景仅限于静态的、不再改变的图片,如果用在列表中,会因为没有处理 update 事件,图片不会更新。
在原来的代码中,依赖原图片的 onload 事件获取原图像的尺寸,并最终用新生成的图片替换了原图片,导致自定义指令的 updated 钩子传入的参数 el 在 DOM 里已经是不存在了,也就没办法找到并更新这个图片了。
由于上述的缺点,本篇文章将换一种思路,不再替换原图像,而是替换原图像的 src,也不再从原图像的 onload 事件中获取其尺寸,而是获取原图像的 src,新创建一个 img 元素,在这个新 img 的 onload 事件中获取尺寸。
在 Vue 的自定义指令中,如果只需要关注 mounted 和 updated 钩子,那么可以使用简写形式,即直接返回一个函数。本篇文章就使用了简写的形式,新的自定义指令代码如下:
export default (el, binding, vnode) => {
const _img = document.createElement('img');
_img.crossOrigin = 'anonymous';
_img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const thumbWidth = binding.value ?? 50;
const thumbHeight = _img.naturalHeight * thumbWidth / _img.naturalWidth;
canvas.width = thumbWidth;
canvas.height = thumbHeight;
try {
ctx.drawImage(_img, 0, 0, thumbWidth, thumbHeight);
} catch (error) {
console.error(error);
return;
}
el.src = canvas.toDataURL();
};
_img.src = vnode.props.src;
}
代码比原来简单得多。在使用上也比原来简单,不需要添加 crossorigin 属性了:
<img v-thumb :src="xxxx" >
End