vuejs 总结之 v-router 懒加载

Vue.js 李丽红
文章标签: vuejs

我们先看看下面这个面试题:

vue-router第一次加载组件资源过多导致加载缓慢,如何解决?





答案是:通过路由懒加载的形式来解决这个问题

那么什么是路由懒加载呢?

懒加载也叫延迟加载,路由懒加载是利用Vue.js的异步组件和webpack的代码分割,把不同路由对应的不同组件分割成不同的代码块,当路由被访问时,再去加载对应的组件,然后每次进入一个新页面才加载该页面所需要的资源(也就是异步加载路由)

了解 Vue 的异步组件

 Webpack 的代码分割功能


刚开始我们使用路由可能是下面这样(index.js)

import Vue from 'vue'
import Router from 'vue-router'
import StudentInfo from '@/components/StudentInfo'
import StudentChu from '@/components/StudentChu'
import Exam from '@/components/Exam'
import Login from '@/components/Login'
import Main from '@/components/Main'


export default new Router({
routes: [
{path: '/', name: 'login', component: Login},
{
path: '/main',
name: 'Main',
component: Main,
children:[
{path: 'stuInfo',name: 'stuInfo',component: StudentInfo},
{path: 'stuChu',name: 'stuChu',component: StudentChu},
{path: 'exam',name: 'exam',component:Exam}
]

},
]
})

router/index.js  路由相关信息,该路由文件引入了多个 .vue组件 ,然后export 导出, 

执行 npm run build 会 打包为一个整体 app.js ,

如下面所示

image.png

这样一开始进入页面就会把所有的路由资源都加载,如果项目大,加载的内容就会很多,等待的时间页就会越长,导致给用户的不好的体验效果。



解决这个问题,我们把路由分模块,每次进入一个新页面才加载该页面所需要的资源(也就是异步加载路由)

我们可以像下面这样改写上面的代码

//这里就只导入 vue 和 vue-router,不需要再导入组件

import Vue from 'vue'
import Router from 'vue-router'


const Login=resolve=>require(['@/components/Login'],resolve);
const Main=resolve=>require(['@/components/Main'],resolve);
const StudentInfo=resolve=>require(['@/components/StudentInfo'],resolve);
const StudentChu=resolve=>require(['@/components/StudentChu'],resolve);
const Exam=resolve=>require(['@/components/Exam'],resolve);

//这里的写法不变 export default new Router({
routes: [
{path: '/', name: 'login', component: Login},
{
path: '/main',
name: 'Main',
component: Main,
children:[
{path: 'stuInfo',name: 'stuInfo',component: StudentInfo},
{path: 'stuChu',name: 'stuChu',component: StudentChu},
{path: 'exam',name: 'exam',component:Exam}
]
},
]
})

执行 npm run build 发现,多了很多1.xxxxx.js;2.xxxxx.js 等js文件,如下图所示

原因就是 Webpack 会将每个异步加载都打包成一个.js文件 

image.png



支持分组的写法   推荐!!!

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

const Login=resolve=>require(['@/components/Login'],resolve);
const Main=resolve=>require(['@/components/Main'],resolve);
const StudentInfo = () => import(/* webpackChunkName: "group-foo" */ '@/components/StudentInfo');
const StudentChu = () => import(/* webpackChunkName: "group-foo" */ '@/components/StudentChu');
const Exam = () => import(/* webpackChunkName: "group-foo" */ '@/components/Exam');
export default new Router({
routes: [
{path: '/', name: 'login', component: Login},
{
path: '/main',
name: 'Main',
component: Main,
children:[
{path: 'stuInfo',name: 'stuInfo',component: StudentInfo},
{path: 'stuChu',name: 'stuChu',component: StudentChu},
{path: 'exam',name: 'exam',component:Exam}
]
},
]
})



还可以这样写

// r就是resolve
const centerHome = r => require.ensure([], () => r(require('../pages/home/center-home')), 'center')
const centerInfo = r => require.ensure([], () => r(require('../pages/home/center-info')), 'center')
const centerShop = r => require.ensure([], () => r(require('../pages/home/center-shop.vue')), 'center')

const router = new VueRouter({
    mode: 'hash',
    base: __dirname,
    scrollBehavior,
    routes: [
        { name:'center-home', path: '/center/home', component: centerHome },
        { name:'center-info', path: '/center/info', component: centerInfo },
        { name:'center-shop', path: '/center/shop', component: centerShop },
    ]
})

Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。


  • ‘@/’ 和 ‘./’都表示当前路径
  • ‘.vue’后缀可省略
  • ‘center’ 是把组件按组分块打包, 可以将多个组件放入这个组中


还能输出{{restrictNumber}}个字符  
  • {{reply.author}}

    {{CommonUtil.formateDate(reply.ac_CommentDate).shortTime}}
  • 回复了{{Comments.author}} :