javascript - Vue js 预取组件
问题描述
我最近了解了延迟加载组件并开始使用它。现在我正在尝试预取延迟加载的组件以及vue-router
路由。但是使用 chrome devtools 我发现延迟加载的块仅在我们实际导航到延迟加载的路由(在 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")
}
}
}
};
异步路由和组件都被拆分为单独的块,但这些块不是预取的。
当我导航到主视图时,我没有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'
}
),
更新:我尝试使用 webpack 魔术注释删除预取 webpack 插件config.plugins.delete('prefetch');
,然后使用 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>
推荐阅读
- doctrine-orm - Doctrine 2 反向 DQL 成员
- eclipse - Eclipse 启动配置为带有图标的单独工具栏按钮
- javascript - Babel 插件 - 使用索引的成员访问
- javascript - 承诺返回 null
- lua - lua 中的 C# 中的“goto”循环是否有等价物?(必须兼容Love2D)
- build - QBS:qbs.buildVariant 和 qbs.configurationName 有什么区别?
- php - codeigniter 保存任何事务
- ruby-on-rails - Rails 5 设计不保存嵌套属性
- python-3.x - 使用 matplotlib 选择网格覆盖的坐标系
- javascript - 如何根据类别对产品进行排序