【问题标题】:How to preload images using Vue.js?如何使用 Vue.js 预加载图像?
【发布时间】:2018-06-13 21:34:27
【问题描述】:

我有一个使用 Vue.Js(带有 webpack)的小应用程序。我有一个过渡部分。当用户单击按钮时,内容将发生变化。这是一个简单的DIV 元素,带有一个IMG 子元素。我的问题是当用户点击按钮时,下一张图片会实时加载,速度很慢,所以我需要预加载这些图片。

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

  • 只有第一个图像是 DOM 的一部分,当页面显示时,不会加载其他图像。好的,这是正常行为。

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

  • 我尝试使用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


    【解决方案1】:

    我很快在浏览器中尝试了这个,但它似乎在控制台中工作。您可以使用 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。

    如果我在这方面错了,请有人纠正我,但还没有完全尝试过。

    【讨论】:

    • 首先感谢您的回答!我也试过这个,但有趣的是它也不适合我。我会再试一次这种方法,我会写下结果......也许我犯了一个错误......
    • 通过 chrome 网络选项卡检查网络请求是否真的为图像触发。也可以通过控制台手动试一试,进行测试。
    • @EdmundElmer 我遇到了同样的问题。你找到解决办法了吗?
    • 你也可以使用document.createElement('img').setAttribute('src', '/static/myimage');,但它本质上是一样的,都可以工作。
    • 为我工作。请注意,每个新图像实例都会预加载一个图像,因此有必要为要预加载的每个图像创建一个new Image()
    【解决方案2】:

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

    示例:

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

    【讨论】:

    • 这不起作用,因为就 DOM 而言,标签不存在,直到您显示它并放置一个 src。至少对我来说,在 for 循环中它不起作用。您是否想到了其他适用的环境?
    • 我认为@Fraccier 的意思是通过页面加载循环为以后需要的每个图像URL 创建img 元素,并通过CSS 无限期地隐藏这些元素。因此,URL 被预加载在浏览器缓存中,并且可以被其他元素自动访问。基本上让浏览器完成繁重的工作。 This guy has done a similar approach, works fine for me
    【解决方案3】:

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

    在路由器中

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

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 2011-08-25
      • 2011-04-08
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多