In Vue2, asynchronous component processing can be easily implemented using import. However, in Vue 3.x, the use of asynchronous components is completely different from Vue 2.x.
- There are three main changes:
- Change of asynchronous component declaration method: Vue 3.x adds an auxiliary function defineAsyncComponent to display and declare asynchronous components
- The component option in the asynchronous component advanced declaration method is renamed loader
- The component loading function bound by loader no longer receives the resolve and reject parameters, and must return a Promise
Auxiliary function defineAsyncComponent
In Vue 2.x, to declare an asynchronous component, you only need to:
const asyncPage = () => import('./views/home.vue')
However, when it comes to Vue 3.x, the above usage does not apply.
- example:
<template> <div> <h1>Async Components</h1> <p>Asynchronous component testing</p> <child></child> </div> </template> <script> const child = () => import('@/components/async-component-child.vue') export default { name: 'async-components', components:{ 'child': child } }; </script>
Asynchronously loaded components will no longer be displayed on the page, and the console will report an error.
In Vue 3.x, the import of asynchronous components needs to be explicitly declared using the auxiliary function defineAsyncComponent. As follows:
<template> <div> <h1>Async Components</h1> <p>Asynchronous component testing</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>
-
Vue 3.x introduces the defineAsyncComponent helper function for the following reasons:
Translated as follows:Now, in Vue 3 Because function components are defined as pure functions, asynchronous component definitions need to be wrapped in a new defineAsyncComponent helper To explicitly define.
The component option is renamed loader
Asynchronous components in Vue 2.x are declared in a more advanced manner.
const asyncPageWithOptions = { component: () => import('./views/home.vue'), delay: 200, timeout: 3000, error: ErrorComponent, loading: LoadingComponent }
Therefore, the following asynchronous component declaration
const asyncPage = () => import('./views/home.vue')
Equivalent to
const asyncPageWithOptions = { component: () => import('./views/home.vue') }
Similarly, asynchronous components can be declared in Vue 3.x. However, the component needs to be changed to loader.
const asyncPageWithOptions = defineAsyncComponent({ loader: () => import('./views/home.vue'), delay: 200, timeout: 3000, error: ErrorComponent, loading: LoadingComponent })
The component loading function no longer receives the resolve and reject parameters, and must return a Promise
In addition, the asynchronous component loading function of Vue 3.x will no longer receive resolve and reject, and must always return Promise
// 2.x version const oldAsyncComponent = (resolve, reject) => { /* ... */ } // 3.x version const asyncComponent = defineAsyncComponent( () => new Promise((resolve, reject) => { /* ... */ }) )
That is, the factory function defines the way to receive the resolve callback. Asynchronous components cannot be used in Vue 3.x:
export default { components: { asyncPage: resolve => require(['@/components/list.vue'], resolve) }, }
Distinction between lazy loading and routing
However, if the project is built with vite tool and import ed for lazy loading in local development, it can be loaded normally, but a warning will be reported; An error will be reported when packaging to the production environment, and the page will not be displayed normally.
Implementation method of route lazy loading:
- defineAsyncComponent method
// router/index.js import { defineAsyncComponent } from 'vue' const _import = (path) => defineAsyncComponent(() => import(`../views/${path}.vue`)); const routes = [ { path: '/async-component', name: 'asyncComponent', component: _import('home'), } ];
- import.meta.glob method
// 1. The above method is equivalent to loading all. vue files in the views directory at one time and returning an object const modules = import.meta.glob('../views/*/*.vue'); const modules ={ "../views/about/index.vue": () => import("./src/views/about/index.vue") } // 2. Direct reference during dynamic import const router = createRouter({ history: createWebHistory(), routes: [ // ... { path: 'xxxx', name: 'xxxxx', // The original method is feasible in development, but not in production // component: () => import(`../views${menu.file}`), // Change to the following component: modules[`../views${filename}`] } // ... ], })
Writing of asynchronous components
<template> <div> <h1>Async Components</h1> <p>Asynchronous component testing</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>
Summary: in short, the asynchronous loading written in the routing configuration file is the use of lazy routing loading, and the asynchronous loading written in the component is the use of asynchronous components.
Welcome to: Personal blog address