Arco Design Pro Vue - 动态路由

学习中,之前用的element-admin-vue(下文简称element)
在element里,使用动态路由时候,我的页面地址都是通过后台接口请求回来的。如下图所示:
在这里插入图片描述
这里后端同事返回的数据是没有经过处理的,都只有一层。于是在这儿需要进项处理。

export const Layout = () => import('@/layout/default-layout.vue');

const MyRoutermodules = import.meta.glob('/src/views/*/*.vue');

export const getRouters = (
  data: any[],
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  pageCode = 'pageCode',
  parentPage = 'parentPage'
) => {
  window.console.log(MyRoutermodules);
  const routerList: any[] = [];
  const btnList: any[] = []; // methodType 1
  const colList: any[] = []; // methodType 2
  const tabList: any[] = []; // methodType 3
  const map: any = {};
  if (!Array.isArray(data)) {
    return routerList;
  }
  data.forEach((item) => {
    delete item.children;
  });
  data.forEach((item) => {
    map[item.pageCode] = item;
  });
  data.forEach((item) => {
    const parent = map[item[parentPage]];
    if (parent) {
      if (!parent.children) {
        parent.children = [];
      }
      Object.keys(item.pageButtons).forEach((i) => {
        switch (item.pageButtons[i].methodType) {
          case 1:
            btnList.push(item.pageButtons[i]);
            break;
          case 2:
            colList.push(item.pageButtons[i]);
            break;
          case 3:
            tabList.push(item.pageButtons[i]);
            break;
          default:
            break;
        }
      });
      parent.children.push({
        name: item.pageName,
        path: item.pagePath,
        component: () =>
          MyRoutermodules[`/src/views/${parent.pagePath}/${item.pagePath}.vue`],
        meta: {
          hidden: item.isHidden,
          // icon: item.icon,
          requiresAuth: true,
          keepAlive: true,
          order: 100,
          roles: ['*'],
          locale: `menu.${parent.pagePath}.${item.pagePath}`,
        },
      });
    } else {
      item.name = item.pageName;
      item.path = `/${item.pagePath}`;
      item.component = Layout;
      item.meta = {
        hidden: item.isHidden,
        // icon: item.icon,
        icon: 'icon-dashboard',
        order: 99,
        locale: `menu.${item.pagePath}`,
      };
      Object.keys(item.pageButtons).forEach((i) => {
        switch (item.pageButtons[i].methodType) {
          case 1:
            btnList.push(item.pageButtons[i]);
            break;
          case 2:
            colList.push(item.pageButtons[i]);
            break;
          case 3:
            tabList.push(item.pageButtons[i]);
            break;
          default:
            break;
        }
      });
      routerList.push(item);
    }
  });
  return { routerList, btnList, colList, tabList };
};

之前没有写过ts,这里路由他是有写一些参数的规则验证,比如order(排序),locale(中英文)等等,因为是练习,用的以前的接口,。所以有些字段是没有的,就在这儿写死了。routerList 就是路由表,btnList,colList,tabList 是页面中 按钮,table列,tabs块的权限。

在element里,配置了动态路由后添加在路由表里,就可以在页面进项跳转操作。
但在arco里,可能是我还没看懂,配置完了之后,添加到路由表里,菜单栏可以显示出来,但是点击的时候跳转是失败的,报错找不到页面。后来试了试,在路由列表里再去把所有的配置都加上。就可以正常跳转了。

import { DEFAULT_LAYOUT } from '../base';
import { AppRouteRecordRaw } from '../types';

const REPORTMODULE: AppRouteRecordRaw = {
  path: '/reportModules',
  name: 'reportModules',
  component: DEFAULT_LAYOUT,
  meta: {
    locale: 'menu.reportModules',
    requiresAuth: true,
    icon: 'icon-dashboard',
    order: 1,
  },
  children: [
    {
      path: 'ProjectSearch',
      name: 'ProjectSearch',
      component: () => import('@/views/reportModules/ProjectSearch.vue'),
      meta: {
        locale: 'menu.reportModules.ProjectSearch',
        requiresAuth: true,
        roles: ['*'],
      },
    },

    {
      path: 'reportList',
      name: 'reportList',
      component: () => import('@/views/reportModules/reportList.vue'),
      meta: {
        locale: 'menu.reportModules.reportList',
        requiresAuth: true,
        roles: ['*'],
      },
    },
    {
      path: 'Subscribe',
      name: 'Subscribe',
      component: () => import('@/views/reportModules/Subscribe.vue'),
      meta: {
        locale: 'menu.reportModules.Subscribe',
        requiresAuth: true,
        roles: ['*'],
      },
    },
    {
      path: 'SpeTracking',
      name: 'SpeTracking',
      component: () => import('@/views/reportModules/SpeTracking.vue'),
      meta: {
        locale: 'menu.reportModules.SpeTracking',
        requiresAuth: true,
        roles: ['*'],
      },
    },
  ],
};

export default REPORTMODULE;

看了一下路由守卫的配置,好像是用后台接口请求的路由与前端写的路由进行对比,再做的权限判断。

import type { Router, RouteRecordNormalized } from 'vue-router';
import NProgress from 'nprogress'; // progress bar

import usePermission from '@/hooks/permission';
import { useUserStore, useAppStore } from '@/store';
import { appRoutes } from '../routes';
import { WHITE_LIST, NOT_FOUND } from '../constants';

export default function setupPermissionGuard(router: Router) {
  router.beforeEach(async (to, from, next) => {
    const userStore = useUserStore();
    const appStore = useAppStore();
    const Permission = usePermission();
    let permissionsAllow = Permission.accessRouter(to);
    if (appStore.menuFromServer) {
      permissionsAllow = true; // 我写死的。
      // 针对来自服务端的菜单配置进行处理
      // Handle routing configuration from the server

      // 根据需要自行完善来源于服务端的菜单配置的permission逻辑
      // Refine the permission logic from the server's menu configuration as needed
      if (
        !appStore.appAsyncMenus.length &&
        !WHITE_LIST.find((el) => el.name === to.name)
      ) {
        await appStore.fetchServerMenuConfig();
      }
      const serverMenuConfig = [
        ...JSON.parse(JSON.stringify(appStore.appAsyncMenus)),
        ...WHITE_LIST,
      ];
      let exist = false;
      while (serverMenuConfig.length && !exist) {
        const element = serverMenuConfig.shift();
        if (element?.name === to.name) exist = true;
        if (element?.children) {
          serverMenuConfig.push(
            ...(element.children as unknown as RouteRecordNormalized[])
          );
        }
      }
      if (exist && permissionsAllow) {
        next();
      } else next(NOT_FOUND);
    } else {
      // eslint-disable-next-line no-lonely-if
      if (permissionsAllow) next();
      else {
        const destination =
          Permission.findFirstPermissionRoute(appRoutes, userStore.role) ||
          NOT_FOUND;
        next(destination);
      }
    }
    NProgress.done();
  });
}

关于路由的几个页面有:
router
components > menu
hooks > permission

在这里插入图片描述

### Arco Design Pro Vue 登录实现方法 Arco Design Pro Vue 提供了一套完整的解决方案来构建企业级应用程序,其中包括用户认证和授权功能。为了实现登录功能,通常会涉及以下几个方面: #### 1. 安装依赖库 首先需要确保已经安装了必要的依赖项,包括 `arco-design` 和 `axios` 等用于发起 HTTP 请求的库。 ```bash npm install @arco-design/web-vue axios ``` #### 2. 创建 Login 组件 创建一个新的 Vue 组件文件 `Login.vue` 来处理用户的输入并提交表单数据给服务器验证身份信息。 ```vue <template> <div class="login-container"> <a-form :model="formState" name="normal_login" layout="vertical" @submit.prevent="handleSubmit"> <h1>Sign In</h1> <!-- Username Input --> <a-form-item field="username" label="Username"> <a-input v-model:value="formState.username"/> </a-form-item> <!-- Password Input --> <a-form-item field="password" label="Password"> <a-input-password v-model:value="formState.password"/> </a-form-item> <!-- Submit Button --> <a-button html-type="submit">Log in</a-button> </a-form> </div> </template> <script setup lang="ts"> import { reactive } from 'vue'; import axios from 'axios'; const formState = reactive({ username: '', password: '' }); // Handle Form Submission async function handleSubmit() { try { const response = await axios.post('/api/auth/login', formState); console.log('Response:', response.data); // Redirect or update state after successful login } catch (error) { console.error('Error during login:', error); } } </script> <style scoped> .login-container { max-width: 400px; margin: auto; padding: 2rem; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, .1); } h1 { text-align: center; font-size: 2em; color: #3f51b5; } </style> ``` 此代码片段展示了如何通过 Arco Design 的 `<a-form>` 及其子组件收集用户名密码,并使用 Axios 发送 POST 请求到后端接口 `/api/auth/login` 进行鉴权操作[^3]。 #### 3. 配置路由守卫 为了让未登录状态下无法访问受保护页面,在应用入口处设置全局前置导航钩子来进行拦截判断是否已登录。 ```javascript import router from './router'; // 假设这是项目的路由实例 import store from './store'; // Vuex 或 Pinia 存储状态管理器 router.beforeEach((to, from, next) => { const isAuthenticated = !!store.getters['auth/isAuthenticated']; if (!isAuthenticated && to.meta.requiresAuth) { next({ path: '/login' }); } else { next(); } }); ``` 这段逻辑会在每次切换路径之前检查当前是否有有效的 session/token ,如果有则允许继续浏览;反之重定向至登录页[^4]。 #### 4. 处理 Token 存储与刷新 成功登录之后应该保存 token 到本地存储(如 localStorage/sessionStorage),以便后续请求携带该凭证完成自动续期等功能。 ```typescript function saveToken(token:string){ window.localStorage.setItem('access_token',token); } function loadToken(){ return window.localStorage.getItem('access_token') || ''; } export default{ saveToken, loadToken }; ``` 以上就是基于 Arco Design Pro Vue 实现基本登录流程的方法概述[^1]。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值