预加载图片在Vue中怎么写才有效?

皇甫月怡 阅读 4

我在用Vue做图片轮播,想提前加载下一张图避免切换时白屏,但加了preload好像没起作用。试过在created里new Image(),也试过在template里加,都不行。

下面是我现在的写法,是不是哪里错了?

<template>
  <div>
    <img :src="currentImage" alt="" />
    <link rel="preload" :href="nextImage" rel="external nofollow"  as="image" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentImage: '/img/1.jpg',
      nextImage: '/img/2.jpg'
    }
  }
}
</script>
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
梓涵 Dev
你这个写法有两个问题。按照 HTML 规范,<link> 标签应该放在 <head> 里面,不应该出现在 <body> 或者组件模板里。虽然浏览器容错机制可能会帮你处理,但在 Vue 这种动态渲染的环境下,指望它生效是不靠谱的。

另外,rel="preload" 主要用于告诉浏览器当前页面稍后一定会用到某个资源,通常是在 HTML 加载时静态声明,或者通过 JS 动态插入到 head 中。

对于轮播图这种场景,最稳妥、最符合前端开发直觉的做法还是用 JavaScript 的 new Image() 对象来预加载。你说试过没用,可能是时机不对或者没处理好缓存。

这里有段代码,直接拿去用就行:

methods: {
preloadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = url;
// 如果图片已经缓存,complete 会立即为 true
if (img.complete) {
resolve();
} else {
img.onload = () => resolve();
img.onerror = () => reject(new Error('Failed to load image: ' + url));
}
});
}
},
watch: {
// 监听当前图片变化,提前加载下一张
currentImage() {
if (this.nextImage) {
this.preloadImage(this.nextImage);
}
}
},
mounted() {
// 初始化时也预加载一次
if (this.nextImage) {
this.preloadImage(this.nextImage);
}
}


这样写的好处是你可以确切知道图片什么时候加载完,甚至可以在加载完成后做一些过渡效果。别在 template 里写 link 标签了,那不是干这个用的。
点赞 1
2026-03-01 20:10