跳到主要内容

路由

XinAdmin 作为前后端分离的框架,路由也分为前端和后端两部分,第一是前端页面的路由,指定你可以访问到的页面视图,第二是后端接口的路由,用于与 Laravel Api 服务器进行交互。而菜单则是在后端管理系统中常见的配置,我们通过菜单来访问前端页面,通常已侧边栏的形式展示出来,点击菜单项,即可访问对应的页面。

前端路由

约定式路由

前端页面路由是基于 UmiJs 的文件路由系统,约定在前端项目 src/pages 目录下,放置你的页面文件,文件名就是路由地址, 它根据文件系统自动注册路由,pages 文件夹下的所有 tsx 文件,都将被注册到路由中,比如 src/pages/index.tsx,表示访问 /index 的页面:

.
└── pages
├── index.tsx
└── users.tsx

会得到以下路由配置:

[
{ path: '/', component: '@/pages/index' },
{ path: '/users', component: '@/pages/users' },
];
信息

使用约定式路由时,约定 src/pages 下所有的 tsx 文件即路由。默认忽略了 componentsmodels 文件夹,如果你需要修改默认规则, 可以使用 UmiJSconventionRoutes 配置。

动态路由

Umi Js 约定,带 $ 前缀的目录或文件为动态路由。若 $ 后不指定参数名,则代表 * 通配,比如以下目录结构:

比如:

  • src/pages/users/$id.tsx 会成为 /users/:id
  • src/pages/users/$id/settings.tsx 会成为 /users/:id/settings

举个完整的例子,比如以下文件结构,

+ pages/
+ foo/
- $slug.tsx
+ $bar/
- $.tsx
- index.tsx

会生成路由配置如下:

[
{ path: '/', component: '@/pages/index.tsx' },
{ path: '/foo/:slug', component: '@/pages/foo/$slug.tsx' },
{ path: '/:bar/*', component: '@/pages/$bar/$.tsx' },
];

路由参数

你可以使用 useParams 获取动态路由中的参数,比如路由配置为 /users/:id ,当前访问的路径为 /users/1 ,你可以使用 useParams 获取 id 参数:

// 当前 location /users/1
import { useParams } from '@umijs/max';

export default () => {
const params = useParams();
console.log(params.id);
// 输出:1
};

你也可用使用 useSearchParams 获取查询参数,比如路由配置为 /users?id=1 ,你可以使用 useSearchParams 获取 id 参数:

import { useSearchParams } from '@umijs/max';
export default () => {
const [searchParams, setSearchParams] = useSearchParams();

searchParams.get('a'); // b
searchParams.toString(); // a=b

setSearchParams({ a: 'c', d: 'e' }); // location 变成 /comp?a=c&d=e
};

更多使用方式请参考 UmiJs Route

后端路由

Laravel 中的路由 通过 Illuminate\Support\Facades\Route 注册,基本的路由知识,你可以参考 Laravel Route, 在 XinAdmin 中,我们对 Laravel 的路由进行了扩展,现在你可以使用注解,直接在控制器中注册路由,不需要格外的路由文件,并且自动与方法进行绑定,支持路由中间件与权限中间件。

信息

Attribute 注解为 PHP8 的新特性,如果你不了解,请参考 PHP 文档 PHP Attribute

基本使用

注解路由通过 PHP8 注解,通过解析器对所有的控制器进行解析并且注册路由,以下是一个基本的示例:

use Xin\AnnoRoute\Attribute\GetMapping;
use Xin\AnnoRoute\Attribute\RequestMapping;

#[RequestMapping('/api')]
class UserController extends BaseController
{

#[GetMapping]
public function index(){
return $this->success();
}

}

每一个需要对外访问的控制器类都需要注册一个 RequestMapping 注解,它用来定义当前控制器需要被解析器解析,并且注册路由,如果你没有在你的控制器类中添加 RequestMapping 注解,则方法中的路由注解不会生效,在上面的示例中,UserController 将被解析器解析,并且注册路由,路由前缀为 /api

GetMapping 注解表示当前方法将注册一个 GET 请求,它将自动与当前方法绑定,类似 Laravel 中注册以下路由:

Route::get('/api', [UserController::class, 'index']);

方便的是它不用格外的书写定义文件,只需要一个注解属性就可以完成路由的注册。

你也可以为当前方法定义自有的路径,它们都将自动包含 RequestMapping 的前缀,比如:

// UserController
#[GetMapping('/show')]
public function show(){
return $this->success();
}

上面的示例类似注册以下路由:

Route::get('/api/show', [UserController::class, 'show']);

可用的路由注解

XinAdmin 已经支持常用的集中请求注解

// 注册一个 Get 请求
use Xin\AnnoRoute\Attribute\GetMapping;

// 注册一个 Put 请求
use Xin\AnnoRoute\Attribute\PutMapping;

// 注册一个 Post 请求
use Xin\AnnoRoute\Attribute\PostMapping;

// 注册一个 Delete 请求
use Xin\AnnoRoute\Attribute\DeletsMapping;

绑定多个路由

当然,你也可以为一个方法定义多个路由:

// UserController
#[GetMapping, PostMapping]
public function show(){
return $this->success();
}

上面的示例类似注册以下路由:

Route::get('/api/show', [UserController::class, 'show']);
Route::post('/api/show', [UserController::class, 'show']);

路由参数

路由映射也支持路由参数,您可能需要从 URL 中捕获用户的 ID,您可以通过定义路由参数来实现:

#[GetMapping('/{id}')]
public function show($id){
return $this->success();
}

它将自动将 URL 中的参数传递给方法。 同样它也支持 Laravel 路由的可选参数:

#[GetMapping('/{name?}')]
public function show(?string $name = 'John'){
return $this->success();
}

路由中间件

所有的路由映射都支持中间件,你可以通过注解类的 middleware 参数为路由定义一个中间件,比如:

#[GetMapping(middleware: EnsureTokenIsValid::class)]
public function show(){
return $this->success();
}

它也支持传入中间件数组:

#[GetMapping(
middleware: [
EnsureTokenIsValid::class,
First::class, Second::class
]
)]
public function show(){
return $this->success();
}

如果你想为当前控制器中的所有路由都定义一个中间件,你可以在 RequestMapping 注解中定义 middleware 属性:

#[RequestMapping('/api', middleware: EnsureTokenIsValid::class)]
class UserController extends BaseController
{

#[GetMapping]
public function index(){
return $this->success();
}

}