javascript - 如何在 Vue.js 中正确延迟加载 json 文件以减少包大小?

标签 javascript json vue.js lazy-loading lottie

我在我的项目中使用 Vue.js 和 Laravel,最近使用名为 Lottie 的插件添加了两个动画。每个动画都是一个组件,它们都使用单独的 JSON 文件来对一组 PNG 图像进行动画处理(类似于 PNG 序列)。这两个 JSON 文件本地存储在路径 /public/data/ 下的项目文件夹中。

首先,除非我输入绝对路径(/users/username/documents/projectname/public/data/filename.json),否则不会读取 JSON 文件,有没有办法只需使用 /data/filename.json 即可使其正常工作?

其次,当我在组件中添加以下代码时,我的 JS 文件会按预期编译为单独的 block :

const animationData = () =>
  import("/users/username/documents/projectname/public/data/filename.json");

当动画尝试运行时,出现以下错误:

Invalid prop: type check failed for prop "data". Expected Object, got Function 

found in

---> <VueLottie>

但是,当我在组件中使用正常导入来导入 json 文件时,如下所示,它可以正常工作并显示动画:

import animationData from "/users/username/documents/projectname/public/data/filename.json";

我的动画组件都是这样设置的:

<template>
        <vue-lottie ref="lottie" loop autoplay :data="animationData" :height="400" :width="400"></vue-lottie>
</template>

<script>
    import vueLottie from "vue-lottie-ssr";
    import animationData from '/users/username/documents/projectname/public/data/filename.json'

    export default {
        name: 'animation',
        components: {
            vueLottie
        },
        data () {
            return {
                speed: 1,
                animationData
            }
        },
        computed: {
            lottie () {
                return this.$refs.lottie
            }
        }

    }
</script>

我还尝试在组件安装时通过 axios 调用获取 JSON 文件,但出现了相同的错误。

更新

我更新了代码,以便延迟加载每个组件而不是 JSON 文件。就像这样:

components: {
  WinAnimation: () => import("./WinAnimation.vue");

  LoseAnimation: () => import("./LoseAnimation.vue");
}

但是现在我收到以下错误:

Unknown custom element: <win-animation> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

更新2

我意识到为什么会收到错误消息。正确的方法是在父 vue 文件内的脚本顶部添加以下内容。

const winAnimation = () => import("./WinAnimation.vue");
const loseAnimation = () => import("./LoseAnimation.vue");

然后在导出默认{...}内我忘记添加名称,所以:

components: { winAnimation, loseAnimation }

现在我的代码已经被分割,我的 app.js 文件大小几乎减少了一半! :)

最佳答案

第一 - 不要使用vue-lottie图书馆。如果你看一下源代码,这个库应该提供的主要也是唯一的东西是组件 src/lottie.vue (+它的依赖项 lottie-web ),但由于某种原因,NPM软件包还包含整个演示应用程序包括演示 JSON 文件 (src/assets/pinjump.json)

如果您看一下 lottie.vue 组件,它只是非常小且非常简单的 lottie-web 包装器,提供了主要功能。通过摆脱 vue-lottie 您将获得以下好处:

  1. vue-lottie 完全忽略使用 path instead of animationDatalottie-web 选项之一- 这里的文档不是很清楚,但我猜测通过提供路径,该库将尝试临时下载动画数据,因此您不需要将其包含在 bundle 中。值得一试恕我直言...

  2. 按需加载动画数据

  • 为什么要在 JSON 文件上使用动态导入而不是动态导入整个组件?通过在组件级别创建单独的 block ,动态 block 将不仅包含您的 json 数据,还包含同样不小的 lottie-web 。 Vue 将处理组件的加载,无需任何额外的代码更改......
  • 如果您仍然只想按需加载 JSON 数据,则必须了解 Webpack 动态导入 (import(".....")) 返回 Promise 和 lottie -web (以及 vue-lottie)正在期待对象。所以你必须做这样的事情:
<script>
    import lottie from 'lottie-web';

    const animationData = () =>
       import("/users/username/documents/projectname/public/data/filename.json");

    export default {
      mounted () {
        animationData().then(function(data) {
          this.anim = lottie.loadAnimation({
            // other options 
            animationData: data
          })
        });
      }
    }
</script>

更新

在考虑将第 3 方组件添加到项目中时,您应该始终非常小心。我注意到的另一件事是 lottie-webdestroy()其 API 中的方法。这表明它正在创建一些需要清理的资源(可能是 DOM 元素)。这是 vue-lottie 组件根本无法处理的问题,并且可能会导致应用程序中出现严重的内存泄漏。您可以阅读有关该问题的信息 here

关于javascript - 如何在 Vue.js 中正确延迟加载 json 文件以减少包大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60148501/

相关文章:

java - 使用 Jackson 在运行时将实体动态序列化为其 ID 或其完整表示

java - JSONObject.toString : how NOT to escape slashes

javascript - 当文本具有特殊字符时,offsetWidth 无法正确计算

javascript - 使用 GeoWebCache 时出现“粉红色瓷砖”

json - 在 Angular 中,作为索引类型导入的 json 文件总是返回 undefined

javascript - Vuex:在安装的钩子(Hook)中返回 setter/getter

javascript - 在 Vue/Javascript 中,如何使用对 this.$refs.someDynamicVariable 的动态引用

javascript - Cordova 在输入焦点上禁用收缩 View

javascript - 在 React 文件 : Webpack can't resolve 中包含 NPM 模块

vue.js - 带有 jest + vuejs + vuetify 的意外标识符