在 Vue2
中,异步组件和路由懒加载处理使用 import
就可以很轻松实现。但是在Vue 3.x
中异步组件的使用与 Vue 2.x
完全不同了。本文就详细讲讲vue3
中异步组件
和路由懒加载
的实现。
一、前言
1-1.三点变化:
- 异步组件声明方法的改变:
Vue 3.x
新增一个辅助函数defineAsyncComponent
,用来显示声明异步组件
- 异步组件高级声明方法中的
component
选项更名为loader
loader
绑定的组件加载函数不再接收resolve
和reject
参数,而且必须返回一个Promise
1-2.引入辅助函数defineAsyncComponent
的原因:
现在,在 Vue 3
中,由于函数组件
被定义为纯函数
,异步组件定义需要通过将其包装在一个新的 defineAsyncComponent helper
中来显式定义。
二、Vue 2.x与Vue 3.x定义比较
2-1.异步组件/路由定义比较
- 2-1-1.在
Vue 2.x
中,声明一个异步组件只需这样:
| const asyncPage = () => import('./views/home.vue') |
- 2-1-2.在
Vue 3.x
中,异步组件的导入需要使用辅助函数defineAsyncComponent
来进行显式声明。如下:
| <template> |
| <div> |
| <h1>Async Components</h1> |
| <p>异步组件测试</p> |
| <child /> |
| </div> |
| </template> |
| |
| <script> |
| import { defineAsyncComponent } from 'vue' |
| const child = defineAsyncComponent(() => import('@/components/async-component-child.vue')) |
| |
| export default { |
| name: 'async-components', |
| components:{ |
| 'child': child |
| } |
| }; |
| </script> |
2-2.声明方式比较
- 2-2-1.
Vue 2.x
中异步组件的声明有更高级的声明方式。如下:
| const asyncPageWithOptions = { |
| component: () => import('./views/home.vue'), |
| delay: 200, |
| timeout: 3000, |
| error: ErrorComponent, |
| loading: LoadingComponent |
| } |
所以,下面的异步组件声明:
| const asyncPage = () => import('./views/home.vue') |
等价于:
| const asyncPageWithOptions = { |
| component: () => import('./views/home.vue') |
| } |
- 2-2-2.
Vue 3.x
中也可以这样声明异步组件。只是其中的component
需要改为loader
。如下:
| const asyncPageWithOptions = defineAsyncComponent({ |
| loader: () => import('./views/home.vue'), |
| delay: 200, |
| timeout: 3000, |
| error: ErrorComponent, |
| loading: LoadingComponent |
| }) |
2-3.异步组件加载函数
返回比较
- 2-3-1.在
Vue 2.x
中接收resolve
和reject
:
| |
| const oldAsyncComponent = (resolve, reject) => { |
| |
| } |
- 2-3-2.在
Vue 3.x
中始终返回Promise
:
| |
| const asyncComponent = defineAsyncComponent( |
| () => new Promise((resolve, reject) => { |
| |
| }) |
| ) |
Vue 3.x的异步组件加载函数将不再接收resolve
和reject
,而且必须始终返回Promise
。也就是说,工厂函数接收 resolve
回调的方式定义异步组件在 Vue 3.x
不能使用了。
| |
| export default { |
| components: { |
| asyncPage: resolve => require(['@/components/list.vue'], resolve) |
| }, |
| } |
三、Vue3
实践
提示: 如果是用vite
工具来构建项目,在本地开发使用import
做路由懒加载
,可以正常加载,但是会报警告;打包到生产环境
会报错,页面不会正常展示,可以使用以下两种方法来实现。
3-1.路由懒加载实现
- 3-1-1.
defineAsyncComponent
方法
| |
| import { defineAsyncComponent } from 'vue' |
| const _import = (path) => defineAsyncComponent(() => import(`../views/${path}.vue`)); |
| |
| const routes = [ |
| { |
| path: '/async-component', |
| name: 'asyncComponent', |
| component: _import('home'), |
| } |
| ]; |
| |
| const modules = import.meta.glob('../views/*/*.vue'); |
| const modules ={ |
| "../views/about/index.vue": () => import("./src/views/about/index.vue") |
| } |
| |
| |
| const router = createRouter({ |
| history: createWebHistory(), |
| routes: [ |
| |
| { |
| path: 'xxxx', |
| name: 'xxxxx', |
| |
| |
| |
| component: modules[`../views${filename}`] |
| } |
| |
| ], |
| }) |
3-2.异步组件实现
| <template> |
| <div> |
| <h1>Async Components</h1> |
| <p>异步组件测试</p> |
| <child></child> |
| </div> |
| </template> |
| |
| <script> |
| import { defineAsyncComponent } from 'vue' |
| const child = defineAsyncComponent(() => import('@/components/async-component-child.vue')) |
| |
| export default { |
| name: 'async-components', |
| components:{ |
| 'child': child |
| } |
| }; |
| </script> |
四、总结
简单来说,写在路由
配置文件中的异步加载就是路由懒加载
的用法,而写在组件内部
的异步加载就是异步组件用法。
《Vue3学习与实战》系列
欢迎访问:个人博客地址
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了