vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue页面布局与路由映射

Vue页面布局与路由映射实战教程之RouterView嵌套及动态组件生成详解

作者:念念不忘  必有回响

文章介绍了布局组件在Vue应用中的设计和使用,包括布局组件的核心作用、多层RouterView的嵌套布局、静态组件与动态组件的区别,以及动态路由的优势,通过这些机制,可以实现界面的一致性、灵活的权限控制和菜单扩展,感兴趣的朋友跟随小编一起看看吧

一、布局组件的结构设计

1. 布局组件的核心作用

布局组件(如 AppProvider.vue
)是应用的顶层容器,负责:
1.1 统一头部、侧边栏、页脚等固定结构;
1.2 通过 渲染动态内容;
1.3 保持界面风格一致性。
1.4 共享国际化文件、统一处理elment组件样式等
1.5 和路由配置关联,可以定制多种布局方式

引用

 export default defineComponent({
    name: 'AppProvider',
    inheritAttrs: false,
    props: {
      prefixCls: { type: String, default: prefixCls },
    },
    setup(_props) {
      // 动态改变页面title
      useTitle();
      // 监听屏幕变化
      createBreakpointListen();
      // 添加水印 - 嵌套模式下 不显示水印
      if (!isFrameMode()) useUserWatermark();
      // ElementPlus配置
      const { getElLocale } = useLocale();
      const elConf = computed(() => ({
        locale: getElLocale.value,
        message: { max: 2 },
        zIndex: 3000,
      }));
      return () => (
        <ElConfigProvider {...unref(elConf)}>
          <RouterView />
        </ElConfigProvider>
      );
    },
  });

路由文件示例

import { LAYOUT } from '@/router/constant';
export default [
  {
    path: '/',
    component: LAYOUT,
    meta: { orderNo: 0, child1Hoist: true },
    redirect: PageEnum.BASE_HOME,
    children: [
      {
        path: PageEnum.BASE_HOME,
        name: 'Dashboard',
        meta: { title: '首页', icon: 'bi:house-door-fill', affix: true },
        component: () => import('@/views/dashboard/index.vue'),
      },
    ],
  },
  {
    path: '/',
    component: LAYOUT,
    meta: { hidden: true },
    redirect: '/user-center',
children: [
      {
        name: 'UserCenter',
        path: '/user-center',
        meta: { title: '个人信息', icon: 'el-icon-user', hidden: true },
        component: () => import('@/views/sys/user_center/index.vue'),
      },
    ],
  },
] as AppRouteModule[];

二、多层 RouterView 的嵌套布局

通过嵌套路由,布局组件可支持多层级内容渲染:

<!-- Dashboard.vue (子路由组件) -->
<template>
  <div class="dashboard">
    <Sidebar />
    <div class="content">
      <!-- 渲染嵌套路由内容 -->
      <RouterView />
    </div>
  </div>
</template>

该文件的routerview是要动态渲染的内容区域,和子路由配置关联

三、静态组件 vs 动态组件

1. 静态组件(预定义路由)

定义:在路由配置文件中显式声明路径和组件的组件。
场景:固定功能页面(如登录页、404页)。

// router/routes.ts
const routes = [
  {
    path: "/about",
    component: () => import("@/views/About.vue"), // 静态组件
  },
];

2. 动态组件(运行时生成)

定义:通过接口数据或业务逻辑动态生成路径和组件的组件。
场景:权限控制、菜单配置、微前端集成等。

引入组件

// 动态引入组件
routes = asyncImportRoute(routeList);

路由处理

export function asyncImportRoute(routes: AppRouteRecordRaw[], level = 1) {
  if (routes) {
    dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}');
    routes.forEach((item) => {
      if (!item.component && item.meta?.frameSrc) item.component = 'IFRAME';
      const { component, children, name } = item;
      if (component) {
        const layoutFound = LayoutMap.get((component as string).toUpperCase());
       item.component = layoutFound || dynamicImport(dynamicViewsModules, component as string);
      } else {
        item.component = level === 1 ? LAYOUT : getParentLayout(name);
      }
      if (children && children.length) asyncImportRoute(children, level + 1);
    });
  }
  return routes;
}

dynamicImport

/**
 * 根据组件名导入对应的视图
 *
 * @param dynamicViewsModules 一个记录,键是模块路径,值是返回Promise的函数,该Promise解析为一个记录。
 * @param component 需要动态导入的组件路径,可以是相对路径,且预期以'.vue'或'.tsx'结尾。
 * @returns 如果找到唯一的匹配项,则返回对应模块的加载函数。如果找到多个匹配项或无匹配项,将分别发出警告并返回undefined或EXCEPTION。
 */
function dynamicImport(
  dynamicViewsModules: Record<string, () => Promise<Recordable>>,
  component: string,
) {
 const keys = Object.keys(dynamicViewsModules);
  const matchKeys = keys.filter((key) => {
    const k = key.replace('../../views', '');
    const startFlag = component.startsWith('/');
    const endFlag = component.endsWith('.vue') || component.endsWith('.tsx');
    const startIndex = startFlag ? 0 : 1;
    const lastIndex = endFlag ? k.length : k.lastIndexOf('.');
    return k.substring(startIndex, lastIndex) === component;
  });
  if (matchKeys?.length === 1) {
    const matchKey = matchKeys[0];
    return dynamicViewsModules[matchKey];
  } else if (matchKeys?.length > 1) {
    $log.warn(
      '请不要在`src/views/`同级目录创建后缀为`.vue`或`.tsx`的同名文件, 这将会导致动态引入失败',
    );
    return;
  } else {
    $log.warn('在`src/views/`下找不到`' + component + '`, 请先在前端工程中创建该文件!');
    return EXCEPTION;
  }
}

核心要点:

  1. 对接口返回的动态路由最外层设置component属性值,设置布局组件
  2. 规范组件路由书写文件夹,比如统一在@/views下书写,配置路由的时候根据该目录去配置,动态加载子路由的component

四、 总结

到此这篇关于Vue页面布局与路由映射实战教程之RouterView嵌套及动态组件生成详解的文章就介绍到这了,更多相关vue页面布局与路由映射内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文