javascript - Vue js 预取组件

标签 javascript vue.js webpack code-splitting

我最近了解了延迟加载组件并开始使用它。现在我正在尝试预取延迟加载的组件以及 vue-router路线。但是使用 chrome devtools 我发现延迟加载的 block 仅在我们实际导航到延迟加载的路由(在 vue-router 路由的情况下)或 v-if 时才会加载。计算结果为 true并且组件被渲染(在延迟加载组件的情况下)。
我也尝试过使用 webpackPrefetch: true路由器中的魔术字符串以及组件导入语句,但这样做似乎没有任何区别。
项目结构:
主从布局
路由器配置:

import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);

var routes = [  
  {
    path: "/DetailPage",
    component: () => import(/* webpackChunkName: "Detail-chunk" */ "AppModules/views/MyModuleName/DetailPage.vue")
  },
  {
    path: "/MasterPage",
    component: () => import("AppModules/views/MyModuleName/MasterPage.vue")
  }
]

export const router = new Router({
  routes: routes,
  stringifyQuery(query) {
    // encrypt query string here
  }
});

export default router;
主视图:
<template> 
  <div @click="navigate">
    Some text
  </div>
</template>

<script>
export default {
  name: "MasterPage",
  methods: {
    navigate() {
      this.$router.push({
        path: "/DetailPage",
        query: {},
      });
    },
  },
};
</script>
详情页面:
<template>
  <div>    
    <my-component v-if="showComponent" />
    <div @click="showComponent = true">Show Component</div>
  </div>
</template>

<script>
const MyComponent = () => import(/* webpackChunkName: "MyComponent-chunk" */ "AppCore/components/AppElements/Helpers/MyComponent");
export default {
  name: "DetailPage",
  components: {
    MyComponent,
  },
  data() {
    return {
      showComponent: false
    }
  }
};
</script>
vue.js.config 文件:
const path = require("path");

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

module.exports = {
  publicPath: "some-url",
  outputDir: "./some/path",
  chainWebpack: webapckConfig => {
    webapckConfig.plugin("html").tap(() => {
      return [
        {
          inject: true,
          filename: "index.html",
          template: "./public/index.html"
        }
      ];
    });
  },
  productionSourceMap: true,
  configureWebpack: {
    plugins: [
      new BundleAnalyzerPlugin({
        analyzerMode: "server",
        generateStatsFile: false,
        statsOptions: {
          excludeModules: "node_modules"
        }
      })
    ],
    output: {
      filename: "some file name",
      libraryTarget: "window"
    },
    module: {
      rules: [
        {
          test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
          use: [
            {
              loader: "url-loader",
              options: {
                limit: 50000,
                fallback: "file-loader",
                outputPath: "/assets/fonts",
                name: "[name].[ext]?hash=[hash]"
              }
            }
          ]
        }
      ]
    },
    resolve: {
      alias: {
        vue$: process.env.NODE_ENV == 'production' ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js',
        AppCore: path.resolve(__dirname, "..", "..", "AppCoreLite"),
        AppModules: path.resolve(__dirname, "..", "..", "AppModulesLite")
      }
    }
  }
};
异步路由和组件都被拆分为单独的 block ,但这些 block 不是预取的。
当我导航到主视图时,我看不到 Detail-chunk.[hash].js在网络选项卡中。仅当 navigate 时才被请求执行母版页中的方法(这是没有预取的正确延迟加载行为)。
现在,当我在详细信息页面上时,MyComponent-chunk.[hash].js仅在 showComponent 时才被请求变成 true (点击按钮)
我也在几个地方读到了vue-cli v3 确实默认启用了预取功能,并且不需要 webpack 魔术字符串。我还尝试通过删除 webpackPrefetch评论,但没有任何区别。
我做了vue-cli-service inspect并发现预取插件确实存在于 webpack 配置中:
 /* config.plugin('preload') */
    new PreloadPlugin(
      {
        rel: 'preload',
        include: 'initial',
        fileBlacklist: [
          /\.map$/,
          /hot-update\.js$/
        ]
      }
    ),
    /* config.plugin('prefetch') */
    new PreloadPlugin(
      {
        rel: 'prefetch',
        include: 'asyncChunks'
      }
    ),
更新:我尝试使用 config.plugins.delete('prefetch'); 删除预取 webpack 插件然后使用 webpack 魔术注释:/* webpackPrefetch: true */但这没有任何区别。
如何实现预取功能?

最佳答案

我通过创建一个在自定义时间后加载的简单预取组件解决了这个问题。
预取.vue

<script>
import LazyComp1 from "./LazyComp1.vue";
import LazyComp2 from "./LazyComp2.vue";
export default {
    components:{
        LazyComp1,
        LazyComp2,
    }
}
</script>
应用程序.vue
<template>
    <Prefech v-if="loadPrefetch"></Prefech>
</template>
<script>
export default {
    components: {
        Prefech: () => import("./Prefetch");
    },
    data() {
        return {
            loadPrefetch: false
        }
    },
    mounted() {
        setTimeout(() => {
            this.loadPrefetch = true;
        }, 1000);
    }
}
</script>

关于javascript - Vue js 预取组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63519255/

相关文章:

javascript - Node.js 应用程序无法在 Safari 或 Internet Explorer 中运行

javascript - Vue 在方法调用期间不会更新组件本地的数据

javascript - npm 错误! FetchError : request to http://registry. npmjs.org/webpack-dev-server 失败,原因 : connect ECONNREFUSED 127. 0.0.1:8000

javascript - JS OR 运算符不适用于 v-bind Vue.js

javascript - 标签生成器功能 - 检查字符串是否符合要求

javascript - VueJS 中的 promise 问题

email - 通过 webpack vuejs 发送邮件

javascript - Cloudinary 响应式图像仅在使用 Webpack 的 React 中的窗口大小变化时显示

javascript - 从 REST API 填充多选 select2 选项

javascript - Vue Array 转换为 Proxy 对象