美文网首页
Vue 路由懒加载问题

Vue 路由懒加载问题

作者: BA_凌晨四点 | 来源:发表于2021-04-18 14:55 被阅读0次

    首先描述一下我的开发环境配置:

    1. vue: 2.6.11
    2. vue-router: 3.2.0
    3. 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开发者社区那看到这位老哥的回答:

    router.png
    说这是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`)  
      },
    

    成功了,报错信息消失了。。,新的问题又出现了。。。我的页面组件呢。。?
    我发现路由不是懒加载了,而是直接不加载了。。。

    路由不加载.gif
    按路由切换,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,然后名字和该页面组件名字保持一致
      },
    // ... 下面配置路由同上,此处省略
    ]
    

    相关文章

      网友评论

          本文标题:Vue 路由懒加载问题

          本文链接:https://www.haomeiwen.com/subject/htxvlltx.html