路由器级别的 Vue 3 动态组件

Posted

技术标签:

【中文标题】路由器级别的 Vue 3 动态组件【英文标题】:Vue 3 dynamic components at router level 【发布时间】:2021-08-29 02:29:45 【问题描述】:

我需要动态导入,例如。我有 10 个布局,但用户只访问了 3 个布局,我不应该导入所有布局,因为它消耗了不必要的资源。

由于它是动态导入的,每次我在登录和注册路径<RouterLink :to"name: 'Login'" /><RouterLink :to"name: 'Register'" />之间切换时,我都会再次重新渲染或动态导入布局。

我的问题是,在不重新渲染或动态导入布局的情况下,更好的处理方法是什么?或者我可以将动态导入组件保存到当前的 vue 3 上下文中吗?

App.vue 这是我的应用,可以查看路由器并根据 route.meta.layout 切换布局

<template>
  <component :is="layout.component" />
</template>

<script>
import DefaultLayout from "./layout/default.vue";

import 
  ref,
  shallowRef,
  reactive,
  shallowReactive,
  watch,
  defineAsyncComponent,
 from "vue";

import  useRoute  from "vue-router";

export default 
  name: "App",
  setup(props, context) 
    const layout = shallowRef(DefaultLayout);
    const route = useRoute();
    watch(
      () => route.meta,
      async (meta) => 
        if (meta.layout) 
          layout = defineAsyncComponent(() =>
            import(`./layout/$meta.layout.vue`)
          );
         else 
          layout = DefaultLayout;
        
      ,
       immediate: true 
    );
    return  layout ;
  ,
;
</script>

router/index.js这是我的带有布局元的路由器

import  createRouter, createWebHistory  from "vue-router";
import Home from "@/views/Home.vue";
import NotFound from "@/views/NotFound.vue";

const routes = [
  
    path: "/",
    name: "Home",
    component: Home,
  ,
  
    path: "/login",
    name: "Login",
    meta: 
      layout: "empty",
    ,
    component: function () 
      return import(/* webpackChunkName: "login" */ "../views/Login.vue");
    ,
  ,
  
    path: "/register",
    name: "Register",
    meta: 
      layout: "empty",
    ,
    component: function () 
      return import(/* webpackChunkName: "register" */ "../views/Register.vue");
    ,
  ,
   path: "/:pathMatch(.*)", component: NotFound ,
];

const router = createRouter(
  history: createWebHistory(import.meta.env.VITE_GITLAB_BASE_PATH),
  routes,
  scrollBehavior(to, from, savedPosition) 
    // always scroll to top
    return  top: 0 ;
  ,
);

export default router;

【问题讨论】:

&lt;component :is="layout.component"&gt; &lt;router-view&gt;&lt;/router-view&gt; &lt;/component&gt;怎么样 不,&lt;router-view&gt;&lt;/router-view&gt; 放在我的布局下... 我觉得你不需要动态导入布局 @BoussadjraBrahim 怎么样?为什么?我需要不同路线的不同布局 好的,我明白了。但是,我仍然需要动态导入,例如。我有 10 个布局,但用户只访问了 3 个布局,我不应该导入所有布局,因为它消耗了不必要的资源,谢谢! 【参考方案1】:

您可以在 components 选项中使用 AsyncComponent 并仅使用返回当前布局的计算属性,这将仅加载当前布局而不加载其他布局:

components: 
        layout1: defineAsyncComponent(() => import('./components/Layout1.vue')),
        layout2: defineAsyncComponent(() => import('./components/Layout2.vue')),
,

【讨论】:

以上是关于路由器级别的 Vue 3 动态组件的主要内容,如果未能解决你的问题,请参考以下文章

Vue 动态组件 vs 路由器

Nuxt 中同一级别的多个动态路由可能吗?

vue-动态路由的实现

Vue2 - 路由级别的延迟加载不起作用?

vue中动态路由组件缓存及生命周期函数

vue路由-动态路由和嵌套路由