上一篇文章的自定义指令非常简陋,使用场景仅限于静态的、不再改变的图片,如果用在列表中,会因为没有处理 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

标签: Vue自定义指令, vue3

仅有一条评论

  1. 2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

添加新评论