vue组件懒加载
vue组件懒加载1 路由懒加载路由懒加载常用的两种方式是import(官方推荐)和requireVue官网路由懒加载开发文档路由懒加载 | Vue Router1.1 使用import实现懒加载routerimport Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)/*// 原始加载方式import View
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,脚本运行时动态加载对象。
更多推荐



所有评论(0)