不要在路由中使用异步组件

Posted 前端精髓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不要在路由中使用异步组件相关的知识,希望对你有一定的参考价值。

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:

// 将
// import UserDetails from './views/UserDetails'
// 替换成
const UserDetails = () => import('./views/UserDetails')

const router = createRouter(
  // ...
  routes: [ path: '/users/:id', component: UserDetails ],
)

component (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router 只会在第一次进入页面时才会获取这个函数,然后使用缓存数据。

一般来说,对所有的路由都使用动态导入是个好主意。

注意:不要在路由中使用异步组件。异步组件仍然可以在路由组件中使用,但路由组件本身就是动态导入的。

Vue3 支持 defineAsyncComponent() 方法定义一个异步组件,它在运行时是懒加载的。参数可以是一个加载函数,或是对加载行为有更进一步控制的一个选项对象。

在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。为实现这点,Vue 提供了一个 defineAsyncComponent 方法:

import  defineAsyncComponent  from 'vue'

const AsyncComp = defineAsyncComponent(() => 
  return new Promise((resolve, reject) => 
    // ...从服务器获取组件
    resolve(/* 获取到的组件 */)
  )
)
// ... 像使用其他一般组件一样使用 `AsyncComp`

如你所见,defineAsyncComponent 方法接收一个返回 Promise 的加载函数。这个 Promise 的 resolve 回调方法应该在从服务器获得组件定义时调用。你也可以调用 reject(reason) 表明加载失败。

对于 defineAsyncComponent 使用场景,有的需求会想要在两个组件间来回切换,比如 Tab 界面:

<!-- currentTab 改变时组件也改变 -->
<component :is="currentTab"></component>

上面的例子是通过 Vue 的动态组件实现视图切换的。

<script lang="ts">
import  ref, defineAsyncComponent  from 'vue'

const AsyncComp1 = defineAsyncComponent(() =>
  import('./components/MyComponent1.vue')
)
const AsyncComp2 = defineAsyncComponent(() =>
  import('./components/MyComponent2.vue')
)

export default 
  components: 
    AsyncComp1,
    AsyncComp2
  ,
  setup() 
    const currentTab = ref('AsyncComp1')

    function change() 
      currentTab.value = currentTab.value === 'AsyncComp1' ? 'AsyncComp2' : 'AsyncComp1'
    
    // console.log(AsyncComp1, 'o')
    return 
      currentTab,
      change
  

</script>

<template>
  <div>
    <div @click="change">切换</div>
    <component :is="currentTab"></component>
  </div>
</template>

但是下面这里是一个 React 的例子,展示如何在你的应用中使用 React.lazy 和 React Router 这类的第三方库,来配置基于路由的代码分割。

import React,  Suspense, lazy  from 'react';
import  BrowserRouter as Router, Routes, Route  from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback=<div>Loading...</div>>
      <Routes>
        <Route path="/" element=<Home /> />
        <Route path="/about" element=<About /> />
      </Routes>
    </Suspense>
  </Router>
);

由于 React Router 没有支持动态导入,所以直接使用 import 语法是不可以的,必须借助 React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件)

以上是关于不要在路由中使用异步组件的主要内容,如果未能解决你的问题,请参考以下文章

不要在路由中使用异步组件

vue路由自动加载、按组件异步载入vuex以及dll优化

Vue中router路由异步加载组件-优化性能

如何在Angular中启动应用程序时调用服务?

使用异步路由时将 props 传递给组件

React 路由使用