首先描述一下我的开发环境配置:
- vue: 2.6.11
- vue-router: 3.2.0
- vue-cli: 3.9.3
目的:
上传Vue项目到服务器时,首次加载,发现请求太慢了,于是到网上找了很多方法,比如:分包、cdn加速、gzip压缩等,其中一个叫做路由懒加载
原先的路由配置方法:
import Vue from "vue";
import VueRouter from "vue-router";
import About from "@/view/About";
// 分别导入各个页面组件,此处省略...
const routes = [
{
path: "/About",
name: "about",
component: About;
},
// ... 下面配置路由同上,此处省略
]
首次载入时,会把全部页面都载入
第一次配置路由懒加载:
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/About",
name: "about",
component: import("@view/About") // 据说这样就是会当地址匹配到时候,才会加载
},
// ... 下面配置路由同上,此处省略
]
第二次配置路由懒加载:
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/About",
name: "about",
component: import(/* webpackChunkName: "about" */ `@/views/About`)
// 这里加上了webpackChunkName,然后名字和该页面组件名字保持一致
},
// ... 下面配置路由同上,此处省略
]
后来,我为了偷懒还封装了一个函数,专门用于生产:
/**
* 生产懒加载的页面函数
* @param {*} view 页面
* @param {*} str 页面名字
*/
function loadView(view, str) {
return () =>
import(
/* webpackChunkName: `${str}-[request]-[index]` */ `@/views/${view}`
);
}
第三次配置路由懒加载:
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/About",
name: "about",
component: resolve => require(["@/view/About"], resolve);
},
// ... 下面配置路由同上,此处省略
]
后来,我去到Vue开发者社区那看到这位老哥的回答:
说这是Webpack版本的差异导致写法的差异:
require
这是CommonJs的写法,而import
是ES6模块化的写法
可是事情就这么结束了吗?
遇到的问题:
我上面三次的配置方式,都会出现一个问题:产生许多的文件。。其中包括css和js等,我认真的看了下,它把我的每个路由都分离了出来,
如果不重命名,则它的名称是:
名称1~名称2.js ,每加多一个文件,就会多一个 “~名称n”
然后我又开始找方法。。
后来找到一个类似的问题,它的解决方法是:
// vue.config.js
// 移除 prefetch 插件
chainWebpack config => {
config.plugins.delete("prefetch"),
config.plugins.delete("preload"),
// 或者 修改它的选项:
config.plugin("prefetch").tap(options => {
options[0].fileBlacklist = options[0].fileBlacklist || [];
options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/);
return options;
});
}
它的大概意思是 vue-cli3搭建的,会自动安装这2个插件,功能是预加载,预判你将要会加载的路径。
然后我按它方法设置了,再npm run build
打包,发现还是没变,文件依然很多。。。
解决方法:
第一次尝试解决:
在上述第二次配置路由的方法中,设置每个webpackChunkName
名字都一样
const routes = [
{
path: "/About",
name: "about",
component: import(/* webpackChunkName: "chunk-all" */ `@/views/About`)
// 每个路由每个都是这个 chunk-all 的名字
},
// ... 下面配置路由同上,此处省略
]
npm run build
,打包后发现,文件确实减少了,之前那些叠加出来的文件消失了。
但是,新的问题出现了。。报错了。。。
[Vue warn]: Failed to mount component: template or render function not defined.
此时,我又在网上找了一圈,有的说由于匹配问题,需要在路由后面加上具体的文件以及它的后缀
{
path: "/About",
name: "about",
component: import(/* webpackChunkName: "chunk-all" */ `@/views/About/index.vue`)
},
可是问题还是没解决。。接着找。。。
该解决方法出来了:
component后面要加上s
{
path: "/About",
name: "about",
components: import(/* webpackChunkName: "chunk-all" */ `@/views/About/index.vue`)
},
成功了,报错信息消失了。。,新的问题又出现了。。。我的页面组件呢。。?
我发现路由不是懒加载了,而是直接不加载了。。。
按路由切换,
router-view
不会解析路径。。。
解决方法来了:
import 需要函数把它引入(注意以下注释部分)
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/About",
name: "about",
component: () => import(/* webpackChunkName: "chunk-all" */ `@/views/About`)
// 注意这里有 箭头函数,而 component不需要加s
},
// ... 下面配置路由同上,此处省略
]
或者:使用require.ensure()
这个方法也行
{
path: "/",
name: "about",
component: resolve =>
require.ensure([], () => resolve(require("@/views/About")), "chunk-all")
// 这里的第三个参数 chunk-all ,后面所有路由都统一使用一样的名字
}
可是,问题就这样结束了吗?
我又发现,如果像上面说的,为了减少生成的文件,而把名字全都设置成chunk-all
,反而失去了css等懒加载。。
问题更新:
我发现,即使生成了很多文件,但是这些文件都不会在首次加载的时候 全部加载的。。
这真正实现的路由懒加载!
最终解决方法:
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/",
name: "about",
component: resolve =>
require.ensure([], () => resolve(require("@/views/About")), "about")
// 这里的第三个参数 和该页面组件名字保持一致
}
// ... 下面配置路由同上,此处省略
]
或者:
import Vue from "vue";
import VueRouter from "vue-router";
const routes = [
{
path: "/About",
name: "about",
component: () => import(/* webpackChunkName: "about" */ `@/views/About`)
// 这里加上了webpackChunkName,然后名字和该页面组件名字保持一致
},
// ... 下面配置路由同上,此处省略
]
网友评论