1 路由懒加载
路由懒加载常用的两种方式是import(官方推荐)和require
Vue官网路由懒加载开发文档
1.1 使用import实现懒加载
router
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) /* // 原始加载方式 import Views from "@/views" import First from "@/views/First" import Second from "@/views/Second" import Third from "@/views/Third" */ // "/* webpackChunkName:'mycomp' */ "的作用是将文件打包在同一个异步块‘mycomp’中 const Views = ()=>import(/* webpackChunkName:'mycomp' */ "@/views") const First = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/First") const Second = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Second") const Third = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Third") const router = new VueRouter({ routes:[ { path:'/', // 一级导航 component: Views, // 二级导航 children:[ { // 重定向到主页 path:'/', redirect:'/first' }, { path:'/first', name:'first', component: First, meta:{ title:"第一个" } }, { path:'/second', name:'second', component: Second, meta:{ title:"第二个" } }, { path:'/third', name:'third', component: Third, meta:{ title:"第三个" } } ] } ] }); // 设置页面标题 router.afterEach((to)=>{ document.title = to.meta.title; }) export default router;
截图
1.2 使用require实现懒加载
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) /* // 原始加载方式 import Views from "@/views" import First from "@/views/First" import Second from "@/views/Second" import Third from "@/views/Third" */ // ---* 1 import方法 *--- // "/* webpackChunkName:'mycomp' */ "的作用是将文件打包在同一个异步块‘mycomp’中 // const Views = ()=>import(/* webpackChunkName:'mycomp' */ "@/views") // const First = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/First") // const Second = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Second") // const Third = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Third") // ---* 2 require方法 *--- const Views = resolve=>(require(["@/views"],resolve)) const First = resolve=>(require(["@/views/First"],resolve)) const Second = resolve=>(require(["@/views/Second"],resolve)) const Third = resolve=>(require(["@/views/Third"],resolve)) const router = new VueRouter({ routes:[ { path:'/', // 一级导航 component: Views, // 二级导航 children:[ { // 重定向到主页 path:'/', redirect:'/first' }, { path:'/first', name:'first', component: First, meta:{ title:"第一个" } }, { path:'/second', name:'second', component: Second, meta:{ title:"第二个" } }, { path:'/third', name:'third', component: Third, meta:{ title:"第三个" } } ] } ] }); // 设置页面标题 router.afterEach((to)=>{ document.title = to.meta.title; }) export default router;
截图
2 组件懒加载
组件懒加载一般有两种方法,一种使用component的is属性和computed实现,另一种是使用v-if实现。
Vue官网动态加载组件开发文档
2.1 页面切换懒加载
在单组件注册中并考虑缓存机制,页面切换懒加载主要有两种实现方式,一种是使用computed、component的is属性、import,另一种是使用computed、component的is属性和require。
<template> <div id="first"> <div class="fir_title"> First Page 河南大学 </div> <div class="fir_nav"> <button v-on:click='switchPage("first")'>FirCom-1</button> <button v-on:click='switchPage("second")'>FirCom-2</button> <button v-on:click='switchPage("third")'>FirCom-3</button> </div> <div class="fir_con"> <component v-bind:is='getFirstCom'></component> </div> </div> </template> <script> /* // ---* 1 使用标签属性is和import *--- const FirstComFirst = ()=>import("./FirstComFirst") const FirstComSecond = ()=>import("./FirstComSecond") const FirstComThird = ()=>import("./FirstComThird") */ // ---* 2 使用标签属性is和require *--- const FirstComFirst = resolve=>(require(["./FirstComFirst"],resolve)) const FirstComSecond = resolve=>(require(["./FirstComSecond"],resolve)) const FirstComThird = resolve=>(require(["./FirstComThird"],resolve)) export default { name: 'First', components: { }, data: function(){ return{ curPage: FirstComFirst } }, methods:{ switchPage: function(page){ switch(page){ case 'first':{ this.curPage = FirstComFirst; break; } case 'second':{ this.curPage = FirstComSecond; break; } case 'third':{ this.curPage = FirstComThird; break; } } } }, computed:{ // 借助计算属性 getFirstCom: function(){ return this.curPage; } } } </script> <style scope lang="less"> .fir_title{ font-weight: bold; } .fir_nav>button{ margin: 10px 6px; } .fir_con{ margin-top: 20px; } </style>
2.2 使用if实现需要时加载
<template> <div id="second"> <div class="sec_title"> Second Page 河南大学 </div> <div class="sec_nav"> <button v-on:click="showFirst()">显示第一个组件</button> <button v-on:click="showSecond()">显示第二个组件</button> </div> <div class="sec_com"> <div>第一个组件</div> <component v-if="isFirstShow" v-bind:is="SecComFirst"></component> <SecComFirstTag v-if="isFirstShow"></SecComFirstTag> </div> <div> <div>第二个组件</div> <component v-if="isSecondShow" v-bind:is="SecComSecond"></component> </div> </div> </template> <script> // 传统方法导入 import SecComFirstTag from "./SecComFirst.vue" export default { name: 'Second', components: { SecComFirstTag }, data: function(){ return{ // Import方法导入 SecComFirst: ()=>import("./SecComFirst"), SecComSecond: ()=>import("./SecComSecond"), isFirstShow: false, isSecondShow: false } }, methods:{ showFirst: function(){ if(this.isFirstShow){ this.isFirstShow = false; }else{ this.isFirstShow = true; } }, showSecond: function(){ this.isSecondShow = this.isSecondShow?false:true; } } } </script> <style scope lang="less"> .sec_title{ font-weight: bold; } .sec_nav>button{ margin: 10px 6px; } .sec_com{ margin: 10px 0px; } </style>
2.3 两种import导入
两种import方式导入组件。
<template> <div id="third"> <div class="th_title"> Third page 河南大学 </div> <div class="th_com"> <component v-bind:is="ThirdComFirst"></component> <ThirdComFirstTag></ThirdComFirstTag> </div> <div class="th_com"> <component v-bind:is="ThirdComSecond"></component> <ThirdComSecondTag></ThirdComSecondTag> </div> </div> </template> <script> // 传统方法导入 import ThirdComFirstTag from "./ThirdComFirst" import ThirdComSecondTag from "./ThirdComSecond" // 下面的方法和传统的方法相似 export default { name: 'Views', components: { ThirdComFirstTag, ThirdComSecondTag }, data: function(){ return{ ThirdComFirst: ()=>import("./ThirdComFirst"), ThirdComSecond: ()=>import("./ThirdComSecond") } } } </script> <style scope lang="less"> .th_title{ font-weight: bold; } .th_com{ margin: 10px 0px; } </style>
3 全部页面代码
3.1 main.js
import Vue from 'vue' import App from './App.vue' import router from '@/router' Vue.config.productionTip = false new Vue({ render: h => h(App), router }).$mount('#app')
3.2 router
index.js
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) /* // 原始加载方式 import Views from "@/views" import First from "@/views/First" import Second from "@/views/Second" import Third from "@/views/Third" */ // ---* 1 import方法 *--- // "/* webpackChunkName:'mycomp' */ "的作用是将文件打包在同一个异步块‘mycomp’中 // const Views = ()=>import(/* webpackChunkName:'mycomp' */ "@/views") // const First = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/First") // const Second = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Second") // const Third = ()=>import(/* webpackChunkName:'mycomp' */ "@/views/Third") // ---* 2 require方法 *--- const Views = resolve=>(require(["@/views"],resolve)) const First = resolve=>(require(["@/views/First"],resolve)) const Second = resolve=>(require(["@/views/Second"],resolve)) const Third = resolve=>(require(["@/views/Third"],resolve)) const router = new VueRouter({ routes:[ { path:'/', // 一级导航 component: Views, // 二级导航 children:[ { // 重定向到主页 path:'/', redirect:'/first' }, { path:'/first', name:'first', component: First, meta:{ title:"第一个" } }, { path:'/second', name:'second', component: Second, meta:{ title:"第二个" } }, { path:'/third', name:'third', component: Third, meta:{ title:"第三个" } } ] } ] }); // 设置页面标题 router.afterEach((to)=>{ document.title = to.meta.title; }) export default router;
3.3 App.vue
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: 'App', components: { } } </script> <style scope lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
3.4 views
index.vue
<template> <div id="views"> <div class="my_nav"> <router-link to="/first">第一个页面</router-link> <router-link to="/second">第二个页面</router-link> <router-link to="/third">第三个页面</router-link> </div> <div class="my_page"> <router-view></router-view> </div> </div> </template> <script> export default { name: 'Views', components: { } } </script> <style scope lang="less"> .my_nav{ height: 40px; } .my_nav>a{ margin: 0 8px } .my_page{ margin-top: 20px; } </style>
3.5 First
index.vue
<template> <div id="first"> <div class="fir_title"> First Page 河南大学 </div> <div class="fir_nav"> <button v-on:click='switchPage("first")'>FirCom-1</button> <button v-on:click='switchPage("second")'>FirCom-2</button> <button v-on:click='switchPage("third")'>FirCom-3</button> </div> <div class="fir_con"> <component v-bind:is='getFirstCom'></component> </div> </div> </template> <script> /* // ---* 1 使用标签属性is和import *--- const FirstComFirst = ()=>import("./FirstComFirst") const FirstComSecond = ()=>import("./FirstComSecond") const FirstComThird = ()=>import("./FirstComThird") */ // ---* 2 使用标签属性is和require *--- const FirstComFirst = resolve=>(require(["./FirstComFirst"],resolve)) const FirstComSecond = resolve=>(require(["./FirstComSecond"],resolve)) const FirstComThird = resolve=>(require(["./FirstComThird"],resolve)) export default { name: 'First', components: { }, data: function(){ return{ curPage: FirstComFirst } }, methods:{ switchPage: function(page){ switch(page){ case 'first':{ this.curPage = FirstComFirst; break; } case 'second':{ this.curPage = FirstComSecond; break; } case 'third':{ this.curPage = FirstComThird; break; } } } }, computed:{ // 借助计算属性 getFirstCom: function(){ return this.curPage; } } } </script> <style scope lang="less"> .fir_title{ font-weight: bold; } .fir_nav>button{ margin: 10px 6px; } .fir_con{ margin-top: 20px; } </style>
FirstComOne.vue
<template> <div> First component one </div> </template> <script> export default { name: 'FirstComOne', components: { } } </script> <style scope lang="less"> </style>
FirstComSecond.vue
<template> <div> First component second </div> </template> <script> export default { name: 'FirstComSecond', components: { }, created: function(){ console.log("FirstComSecond"); } } </script> <style scope lang="less"> </style>
FirstComThird.vue
<template> <div> First component third </div> </template> <script> export default { name: 'FirstComThird', components: { }, created: function(){ console.log("FirstComThird"); } } </script> <style scope lang="less"> </style>
3.6 Second
index.vue
<template> <div id="second"> <div class="sec_title"> Second Page 河南大学 </div> <div class="sec_nav"> <button v-on:click="showFirst()">显示第一个组件</button> <button v-on:click="showSecond()">显示第二个组件</button> </div> <div class="sec_com"> <div>第一个组件</div> <component v-if="isFirstShow" v-bind:is="SecComFirst"></component> <SecComFirstTag v-if="isFirstShow"></SecComFirstTag> </div> <div> <div>第二个组件</div> <component v-if="isSecondShow" v-bind:is="SecComSecond"></component> </div> </div> </template> <script> // 传统方法导入 import SecComFirstTag from "./SecComFirst.vue" export default { name: 'Second', components: { SecComFirstTag }, data: function(){ return{ // Import方法导入 SecComFirst: ()=>import("./SecComFirst"), SecComSecond: ()=>import("./SecComSecond"), isFirstShow: false, isSecondShow: false } }, methods:{ showFirst: function(){ if(this.isFirstShow){ this.isFirstShow = false; }else{ this.isFirstShow = true; } }, showSecond: function(){ this.isSecondShow = this.isSecondShow?false:true; } } } </script> <style scope lang="less"> .sec_title{ font-weight: bold; } .sec_nav>button{ margin: 10px 6px; } .sec_com{ margin: 10px 0px; } </style> 截图
SecComFirst.vue
<template> <div> Second component First </div> </template> <script> export default { name: 'SecComFirst', components: { }, created: function(){ console.log("Second component Frist !") } } </script> <style scope lang="less"> </style>
SecComSecond.vue
<template> <div> Second component Second </div> </template> <script> export default { name: 'SecComSecond', components: { }, created: function(){ console.log("Second component second !") } } </script> <style scope lang="less"> </style>
3.7 Third
index.vue
<template> <div id="third"> <div class="th_title"> Third page 河南大学 </div> <div class="th_com"> <component v-bind:is="ThirdComFirst"></component> <ThirdComFirstTag></ThirdComFirstTag> </div> <div class="th_com"> <component v-bind:is="ThirdComSecond"></component> <ThirdComSecondTag></ThirdComSecondTag> </div> </div> </template> <script> // 传统方法导入 import ThirdComFirstTag from "./ThirdComFirst" import ThirdComSecondTag from "./ThirdComSecond" // 下面的方法和传统的方法相似 export default { name: 'Views', components: { ThirdComFirstTag, ThirdComSecondTag }, data: function(){ return{ ThirdComFirst: ()=>import("./ThirdComFirst"), ThirdComSecond: ()=>import("./ThirdComSecond") } } } </script> <style scope lang="less"> .th_title{ font-weight: bold; } .th_com{ margin: 10px 0px; } </style>
ThirdComFirst.vue
<template> <div> Third component First </div> </template> <script> export default { name: 'ThirdComFirst', components: { }, created: function(){ console.log("Third component Frist !") } } </script> <style scope lang="less"> </style>
ThirdComSecond.vue
<template> <div> Third component Second </div> </template> <script> export default { name: 'ThirdComSecond', components: { }, created: function(){ console.log("Third component second !") } } </script> <style scope lang="less"> </style>
4 import和require的区别
4.1 import/export
来源于ECMAScript2015(ES6),node支持,部分高版本的原生浏览器支持import/export(需要加type="module" 属性),脚本静态编译。
4.2 require/exports
来源于CommonJS,node支持,原生浏览器不支持 require/exports,脚本运行时动态加载对象。