如何使用Vue.js预加载图像?

问题描述 投票:0回答:4

我有一个使用 Vue.Js (带有 webpack)的小应用程序。我有一个过渡部分。当用户单击按钮时,内容会发生变化。这是一个简单的

DIV
元素,带有
IMG
子元素。我的问题是,当用户单击按钮时,下一张图像将实时加载,而且速度很慢,所以我需要以某种方式预加载这些图像。

我尝试了不同的方法,但无法实现图像预加载。问题:

  • 页面显示时,只有第一张图片是 DOM 的一部分,因此不会加载其他图片。好吧,这是正常行为。

  • 我无法通过在图像数组上使用简单的 for 循环来预加载图像(使用 JavaScript 预加载图像),因为每个请求都会通过唯一的查询字符串 (1) 来请求图像。因此预加载的图像名称将与请求的不匹配。

  • 我尝试使用

    require()
    加载图像并将其绑定到 IMG 标签的
    src
    属性。这也没有解决我的问题,当新的
    DIV
    插入到DOM中时,点击后图像将实时加载。

我的简化单文件组件(.vue)看起来像这样:

<template>
    <!-- [FIRST] -->
    <div v-if="contentId == 0">
      <transition
        enter-active-class="animated fadeIn"
        leave-active-class="animated fadeOut"
        mode="out-in">
        <img :src="images.firstScreenShot" key="firstImage">
      </transition>
    </div>
    <!-- [/FIRST] -->

    <!-- [SECOND] -->
    <div v-else-if="contentId == 1">
      <transition
        enter-active-class="animated fadeIn"
        leave-active-class="animated fadeOut"
        mode="out-in">

        <img :src="images.secondScreenShot" key="secondImage">
      </transition>
    </div>
    <!-- [/SECOND] -->
</template>
<script>
    export default {
        data() {
            return {
                contentId: 0,
                images: {
                    firstScreenShot: require('./assets/first-screen-shot.png'),
                    secondScreenShot: require('./assets/second-screen-shot.png'),
                }
            }
        }
    }
</script>

我是Vue.js新手,也许我的方法不好。请告诉我什么是好的方法!

javascript vue.js preload
4个回答
21
投票

我很快在浏览器中尝试了这个,但它似乎在控制台中工作。您可以使用 Javascript Image 对象来预加载图像:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

您可以像这样创建一个新的 Image 对象:

const image = new Image();

然后您可以为该图像分配一个 src 值:

image.src = 'test.jpg'

当您立即向 src 属性提供数据时,浏览器将触发网络请求,这足以加载和缓存图像。这样你就不必将这些图像插入到 DOM 中。

如果我在这一点上错了,有人纠正我,但还没有完全尝试过。


6
投票

如果您使用模板加载带有标签的图像,您可以使用简单的 HTML 来使用 rel="preload" 来预加载图像。

示例:

<img :src="images.secondScreenShot" key="secondImage" rel="preload">

4
投票

我创建一个函数,只需通过参数发送您想要加载的图像对象。

在路由器中

import Digital from '../../images/digital';
import { loadImage } from '../LoadImage';
...

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'welcome',
      component: Welcome,
      beforeEnter(to, from, next) {
         loadImage(Digital);
      }
   }
]

我的功能

export function loadImage(imagesObject) {
  Object.keys(imagesObject).map((key, index) => {
    const img = new Image();
    img.src = imagesObject[key];
  });
}

希望有帮助


0
投票

我也在使用 Vue + Astro。 我不知道这是否适合您,但我使用了

<link v-for="e in list" rel="preload" :href="e.bg.src" as="image"/>
元标记(在正文内),以便在轮播中预加载那些未在第一页中显示(也未在 DOM 中加载)的图像旋转木马。

但是,我认为这种方法对 SEO 不利(不确定)。

© www.soinside.com 2019 - 2024. All rights reserved.