告别硬编码:vue-pure-admin动态路由传参与组件加载新方案

【免费下载链接】vue-pure-admin 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/gh_mirrors/vue/vue-pure-admin

你是否还在为Vue项目中路由传参的繁琐配置而困扰?是否遇到过路由组件路径硬编码导致的维护难题?本文将带你探索vue-pure-admin中基于component路径动态加载的路由传参新方式,让你的路由管理更灵活、更高效。读完本文,你将掌握动态路由配置、组件路径解析和权限控制的实战技巧,轻松应对复杂项目的路由管理需求。

传统路由传参的痛点与挑战

在传统的Vue项目开发中,路由配置往往采用静态方式,组件路径通过字符串硬编码到路由定义中。这种方式在小型项目中或许可行,但随着项目规模扩大,会带来诸多问题:

  • 维护成本高:当组件路径发生变化时,需要手动修改所有相关的路由配置
  • 扩展性差:新增页面或修改路由结构时,需重启开发服务才能生效
  • 权限控制复杂:不同角色需要不同路由权限时,难以实现动态适配

vue-pure-admin作为一款优秀的Vue3后台管理系统模板,提供了一套优雅的解决方案。通过分析src/router/index.tssrc/router/utils.ts的源码实现,我们可以发现其独特的动态路由处理机制。

动态路由加载的核心实现

vue-pure-admin的动态路由加载机制主要依赖于两个关键函数:formatTwoStageRoutesformatFlatteningRoutes。这两个函数在src/router/utils.ts中定义,负责将多层嵌套路由转换为适合Vue Router处理的格式。

/**
 * 一维数组处理成多级嵌套数组(三级及以上的路由全部拍成二级,keep-alive 只支持到二级缓存)
 * https://github.com/pure-admin/vue-pure-admin/issues/67
 * @param routesList 处理后的一维路由菜单数组
 * @returns 返回将一维数组重新处理成规定路由的格式
 */
function formatTwoStageRoutes(routesList: RouteRecordRaw[]) {
  if (routesList.length === 0) return routesList;
  const newRoutesList: RouteRecordRaw[] = [];
  routesList.forEach((v: RouteRecordRaw) => {
    if (v.path === "/") {
      newRoutesList.push({
        component: v.component,
        name: v.name,
        path: v.path,
        redirect: v.redirect,
        meta: v.meta,
        children: []
      });
    } else {
      newRoutesList[0]?.children.push({ ...v });
    }
  });
  return newRoutesList;
}

路由组件的动态导入

在vue-pure-admin中,路由组件的动态导入通过addAsyncRoutes函数实现。该函数会根据后端返回的路由配置,自动匹配并导入对应的组件文件:

function addAsyncRoutes(arrRoutes: Array<RouteRecordRaw>) {
  if (!arrRoutes || !arrRoutes.length) return;
  const modulesRoutesKeys = Object.keys(modulesRoutes);
  arrRoutes.forEach((v: RouteRecordRaw) => {
    // 将backstage属性加入meta,标识此路由为后端返回路由
    v.meta.backstage = true;
    if (v.meta?.frameSrc) {
      v.component = IFrame;
    } else {
      // 对后端传component组件路径和不传做兼容
      const index = v?.component
        ? modulesRoutesKeys.findIndex(ev => ev.includes(v.component as any))
        : modulesRoutesKeys.findIndex(ev => ev.includes(v.path));
      v.component = modulesRoutes[modulesRoutesKeys[index]];
    }
    if (v?.children && v.children.length) {
      addAsyncRoutes(v.children);
    }
  });
  return arrRoutes;
}

这种方式使得路由配置与组件实现解耦,极大提高了系统的灵活性和可维护性。

component路径动态加载的实战应用

在实际开发中,component路径动态加载可以应用于多种场景,如标签页切换、动态表单等。以下是几个典型的应用示例:

1. 标签页组件动态切换

src/views/account-settings/index.vue中,通过动态加载不同的组件实现标签页内容切换:

<template>
  <div class="account-settings">
    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
      <el-tab-pane label="个人资料" name="Profile">
        <component :is="currentComponent" />
      </el-tab-pane>
      <!-- 其他标签页 -->
    </el-tabs>
  </div>
</template>

<script setup lang="ts">
import Profile from "./components/profile.vue";
import Preferences from "./components/preferences.vue";
import SecurityLog from "./components/security-log.vue";
import AccountManagement from "./components/account-management.vue";

const components = [
  { name: "Profile", component: Profile },
  { name: "Preferences", component: Preferences },
  { name: "SecurityLog", component: SecurityLog },
  { name: "AccountManagement", component: AccountManagement }
];

const activeName = ref("Profile");
const currentComponent = computed(() => {
  return components.find(c => c.name === activeName.value)?.component;
});
</script>

2. 动态表单组件加载

src/views/schema-form/index.vue中,通过动态组件实现不同表单类型的切换:

<template>
  <div class="schema-form">
    <el-radio-group v-model="selected" @change="handleChange">
      <el-radio-button :label="0">基础表单</el-radio-button>
      <el-radio-button :label="1">高级表单</el-radio-button>
    </el-radio-group>
    <component :is="currentComponent" />
  </div>
</template>

<script setup lang="ts">
import BasicForm from "./components/basic-form.vue";
import AdvancedForm from "./components/advanced-form.vue";

const selected = ref(0);
const components = [
  { component: BasicForm },
  { component: AdvancedForm }
];

const currentComponent = computed(() => {
  return components[selected.value].component;
});
</script>

3. 表格行内编辑组件

src/views/table/edit.vue中,动态加载不同类型的编辑组件:

<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="name" label="姓名" width="180" />
    <el-table-column prop="age" label="年龄" width="180" />
    <el-table-column label="操作">
      <template #default="scope">
        <el-button @click="handleEdit(scope.row)">编辑</el-button>
      </template>
    </el-table-column>
  </el-table>
  <el-dialog v-model="dialogVisible" title="编辑">
    <component :is="currentComponent" :form-data="formData" />
  </el-dialog>
</template>

<script setup lang="ts">
import TextEditor from "./components/text-editor.vue";
import NumberEditor from "./components/number-editor.vue";
import SelectEditor from "./components/select-editor.vue";

const dialogVisible = ref(false);
const formData = ref({});
const currentComponent = ref(null);

const handleEdit = (row) => {
  formData.value = { ...row };
  dialogVisible.value = true;
  
  // 根据不同类型加载不同编辑器
  if (row.type === 'text') {
    currentComponent.value = TextEditor;
  } else if (row.type === 'number') {
    currentComponent.value = NumberEditor;
  } else {
    currentComponent.value = SelectEditor;
  }
};
</script>

动态路由与权限控制的结合

在企业级应用中,动态路由往往需要与权限控制相结合。vue-pure-admin通过src/router/utils.ts中的filterNoPermissionTree函数实现了基于角色的路由过滤:

/** 从localStorage里取出当前登录用户的角色roles,过滤无权限的菜单 */
function filterNoPermissionTree(data: RouteComponent[]) {
  const currentRoles =
    storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [];
  const newTree = cloneDeep(data).filter((v: any) =>
    isOneOfArray(v.meta?.roles, currentRoles)
  );
  newTree.forEach(
    (v: any) => v.children && (v.children = filterNoPermissionTree(v.children))
  );
  return filterChildrenTree(newTree);
}

这种方式确保了用户只能访问其权限范围内的路由和组件,提高了系统的安全性。

总结与展望

vue-pure-admin的component路径动态加载方案为Vue项目提供了更灵活、更高效的路由管理方式。通过将路由配置与组件实现解耦,不仅降低了维护成本,还大大提高了系统的扩展性和安全性。

未来,随着Web Components标准的普及,我们可以期待更加灵活的组件加载方式。同时,结合微前端架构,动态路由加载机制将在大型应用中发挥更大的作用。

如果你觉得本文对你有帮助,请点赞、收藏并关注我们,获取更多关于vue-pure-admin的实用技巧和最佳实践。下一期我们将探讨"动态路由的性能优化策略",敬请期待!

【免费下载链接】vue-pure-admin 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/gh_mirrors/vue/vue-pure-admin

更多推荐