简体   繁体   中英

How to preload images using Vue.js?

I have a small app using Vue.Js (with webpack). I have a transition section. When the user clicks to a button the content going to change. It's a simple DIV element with an IMG child element. My problem is when the user clicks the button, the next image will be loaded in real-time and it's slow, so somehow I need to preload these images.

I have tried different approaches but couldn't achive the images be preloaded. The problems:

  • Only the first image is the part of the DOM, when page displayed, so the other images will be not loaded. Ok, it's the normal behavior.

  • I couldn't preload the images by using a simple for-loop on an array of images ( Preloading images with JavaScript ), because images will be requested by a unique query string (1 ) to each request. So the preloaded image names will not match with the requested.

  • I tried to load the images using require() and bind it to the IMG tag's src property. It's also not solved my problem, the images will be loaded in real-time after the click when the new DIV will be inserted into the DOM.

My simplified single file compontent (.vue) looks something like that:

<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>

I'm new to Vue.js, maybe my approach is not good. Please let me know what is the good approach!

I quickly tried this out in the browser but it seems to work in console. You can use the Javascript Image object to pre-load images it seems:

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

You can create a new Image object like so:

const image = new Image();

Then you can assign a src value to that image:

image.src = 'test.jpg'

When you supply the src property with data immediately a network request will be fired by the browser which should be sufficient for the image to be loaded and cached. This way you don't have to insert these images into the DOM.

Someone correct me if I am wrong on this though, haven't tried to out fully.

If you are using the template to load the image with the tag you can make use of simple HTML to preload the images using rel="preload" .

example:

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

I create one function just send the image object you want to load via parameter.

in router

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);
      }
   }
]

my function

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

Hope it help

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM