如何使用Vue的内置机制预取图像

时间:2019-01-14 20:38:12

标签: javascript vue.js vuejs2 vue-cli

我有一个使用Vue CLI的应用程序。应用加载后,当用户单击按钮时,我会看到一堆带有过渡的图像。问题在于,当用户单击按钮时,相应的图像才开始加载,这意味着直到那时为止,大多数动画都已完成。这使体验变得非常不稳定,因为在过渡期间图像突然弹出,从而取代了其他元素。我想在网站加载时预取它们。

This answer建议使用Image类。但是,根据Vue CLI docs,Vue内部使用了自己的插件preload-webpack-plugin,并且显然使用了can be configured

我尝试对其进行配置,以使其预加载图像:

vue.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');

module.exports = {
  configureWebpack: {
    plugins: [
      new HtmlWebpackPlugin(),
      new PreloadWebpackPlugin({
        rel: 'prefetch',
        as (entry) {
          if (/\.css$/.test(entry)) return 'style';
          if (/\.woff$/.test(entry)) return 'font';
          if (/\.png$/.test(entry)) return 'image';
          return 'script';
        }
      })
    ]
  }
}

这只能设法弄乱最后的index.html,而使里面没有构建脚本和样式。

如果我删除此行:

      new HtmlWebpackPlugin(),

该站点仍在加载,但未预取图像。就像我从未在vue.config.js文件中做任何事情一样。

如何正确设置?


编辑:在Vue组件中,我使用require()加载图像,这意味着它们通过Webpack传递。例如:

<img :src="require('../assets/img/' + img)" draggable="false">

编辑:我能够按照Roy J在评论中的建议预取图像:

PreloadImages.vue在我的主要组件中:

<template>
  <div style="display: none;">
    <img :src="require('../assets/img/foo.png')">
    <img :src="require('../assets/img/bar.png')">
    <img :src="require('../assets/img/baz.png')">
  </div>
</template>

但是,这不是我的实际问题的答案-它不通过<link>标签使用资源提示。这也需要更多的努力,我认为这是一个不好的做法。

2 个答案:

答案 0 :(得分:1)

由于该插件已经包含在VueJS中,所以我认为您必须使用chainWebpack对其进行修改。

根据预加载的webpack插件documentation,还应该将 include 选项设置为'allAssets'值。

  

在Webpack中,很常见的是使用诸如文件加载器之类的加载器来   生成特定类型的资产,例如字体或图像。如果你   希望也预加载这些文件,您可以将include与value一起使用    allAssets

因此配置将如下所示:

// vue.config.js
module.exports = {
    chainWebpack: config => {
        config.plugin('preload').tap(options => {
            options[0].as = (entry) => {
                if (/\.css$/.test(entry)) return 'style';
                if (/\.woff$/.test(entry)) return 'font';
                if (/\.png$/.test(entry)) return 'image';
                return 'script';
              }
            options[0].include = 'allAssets'
            // options[0].fileWhitelist: [/\.files/, /\.to/, /\.include/]
            // options[0].fileBlacklist: [/\.files/, /\.to/, /\.exclude/]
            return options
        })
    }
}

通过全新的Vue-cli安装,我生成了以下HTML

<!DOCTYPE html>
<html lang=en>

<head>
    <meta charset=utf-8>
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta name=viewport content="width=device-width,initial-scale=1">
    <link rel=icon href=/favicon.ico> <title>vue-preload-images</title>
    <link href=/css/app.0b9b292a.css rel=preload as=style>
    <!-- Here is the logo image -->
    <link href=/img/logo.82b9c7a5.png rel=preload as=image>
    <link href=/js/app.30d3ed79.js rel=preload as=script>
    <link href=/js/chunk-vendors.3d4cd4b5.js rel=preload as=script>
    <link href=/css/app.0b9b292a.css rel=stylesheet>
</head>

<body><noscript><strong>We're sorry but vue-preload-images doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
    <div id=app></div>
    <script src=/js/chunk-vendors.3d4cd4b5.js> </script> <script src=/js/app.30d3ed79.js> </script> </body> </html>

我希望它对您有用。

答案 1 :(得分:0)

解决方案1。

当用户单击按钮时,您将图像渲染为不可见状态。

在图片的load事件中,您可以顺利执行过渡。

如果加载图像通常需要2秒钟以上的时间,请考虑为用户提供视觉线索,单击按钮记录 即将发生。

这将是技术上正确的解决方案。


解决方案2

另一种在生产环境中广泛使用的选择(与Vue本身无关)是在页面中加载图像的缩略图(缩小10倍-缩小约100倍) ,是区域)。可能并不明显,但是当过渡正在进行时,它们可以很好地替代大型的-您可能还想对它们使用CSS blur过滤器进行试验。

在同一个过渡父级中,缩略图和大图像必须完全重叠,且其下方必须有大图像。在大型版本的load事件中,淡出缩略图,产生聚焦效果:微妙的醒目效果。
这种方法的一个有趣之处在于,如果您将拇指放在顶部(使用opacity: 0),则每当有人尝试下载图像时,他们都会右键单击拇指并难以理解为什么要以这种方式下载图像低分辨率。

所有内容(就动画而言)几乎相同,但在实际加载时在图像上增加了聚焦效果。

不是DRY,而是有效的。看起来很专业,一切似乎都能立即流畅地加载。总体而言,它比其他“正确”解决方案的转换方式更多。这就是为什么它通常在页面性能 重要的网站上使用的原因。


在处理视觉效果时,存在是完美的外观(在UX中,感觉/寻找是完美的)。
古代希腊人弯曲他们的柱子,所以从下面看时他们直视