我最近了解了延迟加载组件并开始使用它。现在我正在尝试预取延迟加载的组件以及 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/