使用 h3 路由器允许使用更高级、更方便的路由系统,例如参数和 HTTP 方法,而 app 实例 本身仅允许静态前缀匹配。
!NOTE 在内部,h3 使用 unjs/radix3 进行路由匹配。
用法
首先,您需要使用 createRouter
实用程序创建一个路由器并将其添加到应用程序堆栈。
import { createApp, createRouter, defineEventHandler } from 'h3'
const app = createApp()
const router = createRouter()
app.use(router)
然后,您可以使用名称为 HTTP 方法的方法将路由注册到路由器:
router.get(
'/hello',
defineEventHandler((event) => {
return 'Hello world!'
}),
)
在此示例中,我们为 GET
方法注册路由。这意味着事件处理程序将仅针对 /hello
路由的 GET
请求进行调用。如果您尝试发送 POST
或请求到 /hello/world
,则不会调用事件处理程序。
!NOTE 您仍然可以使用
use
将事件处理程序注册到路由器。它将针对每个 HTTP 方法进行调用。
这意味着您可以使用不同的方法为同一路由注册多个事件处理程序:
router
.get(
'/hello',
defineEventHandler((event) => {
return 'GET Hello world!'
}),
)
.post(
'/hello',
defineEventHandler((event) => {
return 'POST Hello world!'
}),
)
路由参数
您可以使用 :
前缀在路由中定义参数:
router.get(
'/hello/:name',
defineEventHandler((event) => {
return `Hello ${event.context.params.name}!`
}),
)
在此示例中,name
参数将在 event.context.params
对象中可用。
如果您向 /hello/world
发送请求,事件处理程序将返回 Hello world!
。
!NOTE 您可以在路由中使用任意数量的参数。
通配符匹配器
除了命名参数,您还可以使用 *
表示未命名的参数
router.get(
'/hello/*',
defineEventHandler((event) => {
return `Hello ${event.context.params._}!`
}),
)
这将匹配 /hello
和子路由,例如 /hello/world
或 /hello/123
。但它只会匹配一级子路由。
您可以使用 event.context.params._
访问通配符内容,其中 _
是包含通配符内容的字符串。
如果需要匹配多级子路由,可以使用 **
前缀:
router.get(
'/hello/**',
defineEventHandler((event) => {
return `Hello ${event.context.params._}!`
}),
)
这将匹配 /hello
、/hello/world
、/hello/123
、/hello/world/123
等。
!NOTE 参数
_
将把完整的通配符内容存储为单个字符串。
嵌套路由器
您可以嵌套路由器以创建路由器树。这对于将您的应用程序拆分为多个部分(如 API 和网站)很有用。
import { createApp, createRouter, defineEventHandler, useBase } from 'h3'
export const app = createApp()
const websiteRouter = createRouter().get(
'/',
defineEventHandler((event) => {
return 'Hello world!'
}),
)
const apiRouter = createRouter().get(
'/hello',
defineEventHandler((event) => {
return 'Hello API!'
}),
)
websiteRouter.use('/api/**', useBase('/api', apiRouter.handler))
app.use(websiteRouter)
我们创建两个路由器。第一个称为 websiteRouter
,是主路由器。第二个,我们创建第二个路由器,称为 apiRouter
。
然后,我们使用 use
和通配符将 apiRouter
连接到 websiteRouter
,以确保每个以 /api
开头的路由和 HTTP 方法都将由 apiRouter
处理。
!NOTE 不要忘记使用
.handler
从路由器获取事件处理程序。
useBase
用于向路由器的每个路由添加前缀。在此示例中,我们向 apiRouter
的每个路由添加 /api
前缀。因此,路由 /hello
将是 /api/hello
。
最后,我们将 websiteRouter
注册到 app
实例。