在Vue项目开发中,路由懒加载是前端性能优化的核心手段之一。当项目规模扩大、页面增多时,若一次性加载所有路由组件,会导致首屏加载时间过长、资源浪费,影响用户体验。路由懒加载的核心逻辑的是:按需加载,即只有当用户访问该路由时,才加载对应的组件,从而减小首屏加载体积、提升加载速度。
一、路由懒加载核心原理
Vue3项目默认打包时,所有路由对应的组件会被打包到一个app.js文件中,导致该文件体积过大。浏览器加载页面时,需先下载完整个app.js才能渲染页面,首屏加载延迟明显。
Vue3路由懒加载借助ES6的import()动态导入语法,将不同路由对应的组件分割成独立的代码块(chunk)。打包后,每个路由组件对应一个单独的js文件,只有当用户点击该路由、触发路由跳转时,才会异步请求对应的代码块并加载组件,实现“按需加载”。
补充:import()动态导入语法会返回一个Promise对象,Vue Router会自动处理这个Promise,在组件加载完成后渲染页面,无需手动处理异步逻辑,适配Vue3所有版本。
二、路由懒加载的核心优势
路由懒加载是Vue项目性能优化的“低成本、高收益”手段,核心优势主要有3点:
- 减小首屏加载体积:无需加载所有路由组件,只加载当前页面(首页)对应的组件,大幅减小首屏js文件体积,提升首屏加载速度。
- 节省带宽资源:用户未访问的路由组件不会被加载,避免无效资源请求,尤其适合移动端用户(带宽有限场景)。
- 提升用户体验:首屏加载速度加快,减少用户等待时间,降低页面白屏概率;后续路由跳转时,组件异步加载,不阻塞页面渲染。
三、Vue3路由懒加载完整可复制示例(实战必备)
以下提供完整的Vue3路由懒加载示例,包含3个核心文件(router/index.js、main.js、页面组件),代码可直接复制粘贴到项目中使用,无需修改核心逻辑,仅需调整组件路径即可。
1. 路由配置文件(router/index.js)【核心文件】
完整路由配置,包含懒加载语法、路由守卫(可选)、分包策略,适配Vue3+Vue Router 4.x版本:
// router/index.js(Vue3 完整路由懒加载配置)
import { createRouter, createWebHistory } from 'vue-router'
// 路由懒加载核心:用import()动态导入组件,无需提前引入
// 可直接复制,仅需修改组件路径(../views/xxx.vue)
const Home = () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')
const About = () => import(/* webpackChunkName: "About" */ '../views/About.vue')
const User = () => import(/* webpackChunkName: "User" */ '../views/User.vue')
const UserInfo = () => import(/* webpackChunkName: "User" */ '../views/UserInfo.vue')
const NotFound = () => import(/* webpackChunkName: "NotFound" */ '../views/NotFound.vue')
// 完整路由配置(可直接复制使用)
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: '首页', keepAlive: true } // 可选:路由元信息
},
{
path: '/about',
name: 'About',
component: About,
meta: { title: '关于我们' }
},
{
path: '/user',
name: 'User',
component: User,
children: [
// 嵌套路由懒加载(同样适用)
{ path: 'info', name: 'UserInfo', component: UserInfo }
]
},
// 404页面懒加载(必加,提升用户体验)
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
}
]
// Vue3 路由实例创建(固定写法,无需修改)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), // 适配环境变量,避免部署路径问题
routes
})
// 可选:路由守卫(导航前修改页面标题,可删除)
router.beforeEach((to, from, next) => {
document.title = to.meta.title || 'Vue3路由懒加载实战'
next()
})
export default router
2. 入口文件(main.js)【引入路由】
Vue3入口文件,引入路由并挂载到应用,代码可直接复制:
// main.js(Vue3 入口文件,引入路由)
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 引入上面配置的路由
import './assets/main.css' // 可选:项目样式文件
// 挂载路由并创建应用(固定写法)
createApp(App)
.use(router)
.mount('#app')
3. 页面组件示例(views/Home.vue)【配套示例】
简单的页面组件示例,确保路由懒加载可正常渲染,可直接复制:
<!-- views/Home.vue(首页组件示例) -->
<template>
<div class="home">
<h1>Vue3路由懒加载实战</h1>
<div class="router-link">
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="/user">个人中心</router-link>
<router-link to="/user/info">用户信息</router-link>
</div>
<router-view />
</div>
</template>
<script setup>
// 可添加自己的业务逻辑,此处仅作示例
console.log('首页组件(懒加载)已加载')
</script>
<style scoped>
.home {
padding: 20px;
}
.router-link {
margin-right: 20px;
text-decoration: none;
color: #333;
}
.router-link.active {
color: #42b983;
font-weight: bold;
}
</style>
4. 其他页面组件(About.vue/User.vue/NotFound.vue)【简化示例】
其他页面组件可参考以下简化模板,复制后修改内容即可:
<!-- views/About.vue(关于我们组件) -->
<template>
<div class="about">
<h2>关于我们</h2>
<p>Vue3路由懒加载完整示例,可直接复制使用</p>
</div>
</template>
<script setup>
console.log('About组件(懒加载)已加载')
</script>
<!-- views/User.vue(个人中心组件) -->
<template>
<div class="user">
<h2>个人中心</h2>
<router-view />
</div>
</template>
<script setup>
console.log('User组件(懒加载)已加载')
</script>
<!-- views/NotFound.vue(404组件) -->
<template>
<div class="not-found">
<h2>404 Not Found</h2>
<router-link to="/">返回首页</router-link>
</div>
</template>
四、Vue3路由懒加载实现方式(补充说明)
上述示例使用的是Vue3官方推荐的懒加载方式(import()动态导入),也是最简洁、最高效的方式,以下补充2种特殊场景的实现方式,按需选择:
方式1:官方推荐(已在示例中使用,优先选择)
// 简洁写法,可指定chunk名称(便于调试)
const Home = () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')
方式2:结合箭头函数与Promise(兼容低版本环境)
若项目需兼容低版本浏览器(不支持ES6 import()语法),可结合Promise手动处理,本质与方式1一致,只是语法更繁琐,目前已很少使用,仅作兼容参考。
// Vue2 路由配置(Vue3可参考,只需修改路由实例创建方式)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 手动封装懒加载函数(兼容低版本环境)
const lazyLoad = (componentPath) => {
return new Promise((resolve) => {
// 用require动态导入组件,resolve返回组件
require(['../views/' + componentPath + '.vue'], (component) => {
resolve(component.default)
})
})
}
const routes = [
{
path: '/',
name: 'Home',
component: () => lazyLoad('Home') // 调用封装的懒加载函数
},
{
path: '/about',
name: 'About',
component: () => lazyLoad('About')
}
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
方式3:Vue2专属(require.ensure 语法)
这是Vue2早期的路由懒加载方式,基于webpack的require.ensure实现,目前已被import()动态导入替代,仅适用于Vue2+webpack3及以下版本,Vue3不支持。
// 仅Vue2 适用(Vue3不支持)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
// require.ensure(依赖, 回调函数, chunk名称)
component: resolve => require.ensure([], () => resolve(require('../views/Home.vue')), 'Home')
},
{
path: '/about',
name: 'About',
component: resolve => require.ensure([], () => resolve(require('../views/About.vue')), 'About')
}
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
方式4:带加载状态的懒加载(处理网络异常)
添加加载中、加载失败提示,提升用户体验,可替换示例中的路由组件导入:
// 带加载状态的懒加载组件(可直接替换示例中的导入语句)
const Home = () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')
.then(component => component)
.catch(() => {
// 加载失败时,渲染失败提示组件
return import('../components/LoadFail.vue')
})
// 加载中提示(可选,需自行创建Loading组件)
const About = () => import(/* webpackChunkName: "About" */ '../views/About.vue')
.then(component => {
// 模拟加载延迟(实际无需添加)
return new Promise(resolve => setTimeout(() => resolve(component), 500))
})
五、Vue3路由懒加载注意事项
1. 组件路径必须正确
import()中传入的组件路径需是相对路径(以../或./开头),绝对路径会导致打包失败;路径拼写错误会导致组件加载失败,控制台报错“Cannot find module”,需核对views文件夹下的组件名称。
2. 适配Vue Router版本
上述示例适用于Vue Router 4.x(Vue3专属版本),若使用低版本Vue Router,需升级版本(npm install vue-router@4),否则会出现语法错误。
3. 避免过度懒加载
首页、高频访问页面(如首页、个人中心)建议不懒加载,直接打包到首屏js中,避免用户首次访问时出现加载延迟;低频访问页面(如设置、帮助中心)适合懒加载。
4. Vue3与Vue2的路由实例创建差异
Vue3中,路由实例创建方式由new VueRouter()改为createRouter(),且需引入对应的history模式(createWebHistory / createWebHashHistory),懒加载组件的语法与Vue2完全一致,只需注意路由实例的创建差异。
5. 分包策略优化
对于大型项目,可将多个相关路由组件打包到同一个chunk中(如示例中User和UserInfo共用“User”chunk),减少请求次数,提升跳转速度,无需额外配置,只需保证webpackChunkName相同即可。
6. 部署路径注意事项
示例中使用createWebHistory(import.meta.env.BASE_URL),适配不同部署环境(开发、测试、生产),无需手动修改;若直接写死路径(如createWebHistory('/')),部署到子路径时会出现路由跳转异常。
六、进阶优化:路由懒加载结合分包策略
对于大型项目,可结合webpack分包策略,将多个相关路由组件打包到同一个chunk中,减少请求次数。例如,将“用户相关”的路由(User、UserInfo、UserSetting)打包到同一个chunk:
// 同一模块的路由组件,打包到同一个chunk(webpackChunkName相同)
const User = () => import(/* webpackChunkName: "user" */ '../views/User.vue')
const UserInfo = () => import(/* webpackChunkName: "user" */ '../views/UserInfo.vue')
const UserSetting = () => import(/* webpackChunkName: "user" */ '../views/UserSetting.vue')
const routes = [
{ path: '/user', component: User },
{ path: '/user/info', component: UserInfo },
{ path: '/user/setting', component: UserSetting }
]
说明:相同webpackChunkName的组件,打包时会合并到同一个chunk文件(如user.[hash].js),用户访问其中一个路由时,会加载整个chunk,后续访问该模块的其他路由时,无需再次请求,提升跳转速度。
七、进阶优化:路由懒加载结合Pinia
大型项目中,可结合Pinia管理全局状态,在路由懒加载时判断用户权限,示例如下(可直接复制添加到router/index.js):
// 结合Pinia权限判断的路由懒加载(可选)
import { useUserStore } from '@/store/user'
// 权限路由懒加载(需登录才能访问)
const UserSetting = () => {
const userStore = useUserStore()
// 判断用户是否登录,未登录跳转到首页
if (!userStore.token) {
router.push('/')
return import('../views/Login.vue')
}
return import(/* webpackChunkName: "User" */ '../views/UserSetting.vue')
}
// 路由配置中添加
{
path: '/user/setting',
name: 'UserSetting',
component: UserSetting,
meta: { requireAuth: true } // 标记需要权限
}
八、总结
上述提供的Vue3路由懒加载代码可直接复制粘贴到项目中使用,核心是借助import()动态导入语法实现按需加载,优化首屏性能。
实战建议:
- 直接复制router/index.js、main.js和页面组件示例,仅修改组件路径即可快速集成;
- 根据项目需求,添加路由守卫、权限判断、加载状态提示;
- 大型项目结合分包策略,合并相关路由组件,减少请求次数;
- 部署时注意使用import.meta.env.BASE_URL,避免路由跳转异常。
掌握Vue3路由懒加载,是前端性能优化的必备技能,上述完整示例可覆盖大部分项目场景,新手可直接上手,无需额外调试。