Astro 运行时 API
Astro global
段落标题 Astro globalAstro global 在 .astro 文件的所有上下文中都可用。它具有以下功能:
Astro.glob()
段落标题 Astro.glob()Astro.glob() 可以在静态网站 setup 中加载本地文件:
---const posts = await Astro.glob('../pages/post/*.md'); // 返回位于 ./src/pages/post/*.md 的数组并存储在常量 posts 中---
<div>{posts.slice(0, 3).map((post) => ( <article> <h1>{post.frontmatter.title}</h1> <p>{post.frontmatter.description}</p> <a href={post.frontmatter.url}>Read more</a> </article>))}</div>.glob() 只需要一个参数:你想导入的本地文件相对 glob URL。它是异步的并返回数组,这个数组包含匹配文件的导出内容。
.glob() 不接受使用变量或字符串进行插值,因为它们不是静态可分析的。(参见故障排查以了解解决方法)。这是因为 Astro.glob() 是 Vite 的 import.meta.glob() 的包装器。
你也可以在你的 Astro 项目中使用 import.meta.glob()。你可能想在以下情况下这样做:
- 你在一个不是
.astro的文件中需要这个功能,比如一个 API 路由。Astro.glob()只在.astro文件中可用,而import.meta.glob()在项目的任何地方都可用。 - 你不希望立即加载每个文件。
import.meta.glob()可以返回导入文件内容的函数,而不是返回内容本身。请注意,此导入包括任何导入文件的所有样式和脚本。无论文件是否被实际使用,这些样式和脚本都将被捆绑并添加到页面中,因为这是由静态分析决定的,而不是在运行时决定的。 - 你想访问每个文件的路径。
import.meta.glob()返回文件路径到其内容的映射,而Astro.glob()返回内容的列表。 - 你想传递多种模式;例如,你想添加一个“负模式”,过滤掉某些文件。
import.meta.glob()可以选择接受 glob 字符串数组,而不是单个字符串。
在 Vite 文档中阅读更多内容。
Markdown 文件
段落标题 Markdown 文件使用 Astro.glob() 加载的 Markdown 文件返回以下 MarkdownInstance 接口:
export interface MarkdownInstance<T extends Record<string, any>> { /* 在此文件的 YAML frontmatter 中指定的任何数据 */ frontmatter: T; /* 该文件的文件绝对路径 */ file: string; /* 该文件的渲染路径 */ url: string | undefined; /* 渲染此文件内容的 Astro 组件 */ Content: AstroComponentFactory; /** (仅限 Markdown) Markdown 文件的原始内容,不包括布局 HTML 和 YAML frontmatter */ rawContent(): string; /* (仅限 Markdown) Markdown 文件编译后的 HTML,不包括布局 HTML */ compiledContent(): string; /* 返回该文件中 h1...h6 元素数组的函数 */ getHeadings(): Promise<{ depth: number; slug: string; text: string }[]>; default: AstroComponentFactory;}你可以选择使用 TypeScript 泛型指定 frontmatter 变量类型:
---interface Frontmatter { title: string; description?: string;}const posts = await Astro.glob<Frontmatter>('../pages/post/*.md');---
<ul> {posts.map(post => <li>{post.frontmatter.title}</li>)}</ul>Astro 文件
段落标题 Astro 文件Astro 文件具有以下接口:
export interface AstroInstance { /* 此文件的文件路径 */ file: string; /* 此文件的 URL(如果它在 pages 目录中)*/ url: string | undefined; default: AstroComponentFactory;}其他文件
段落标题 其他文件其他文件可能有各种不同的接口,但如果你不知道文件类型包含什么,那么 Astro.glob() 可以接受 TypeScript 泛型。
---interface CustomDataFile { default: Record<string, any>;}const data = await Astro.glob<CustomDataFile>('../data/**/*.js');---Astro.props
段落标题 Astro.propsAstro.props 是一个包含任何作为组件属性传递的值的对象。.md 和 .mdx 文件的布局组件接收作为参数的 frontmatter 值。
---const { title, date } = Astro.props;---<div> <h1>{title}</h1> <p>{date}</p></div>---import Heading from '../components/Heading.astro';---<Heading title="我的第一篇文章" date="09 Aug 2022" />Astro.params
段落标题 Astro.paramsAstro.params 是一个包含与此请求匹配的动态路由段的值的对象。
在静态构建中,这将是 getStaticPaths() 返回的params,用于预渲染 动态路由。
---export function getStaticPaths() { return [ { params: { id: '1' } }, { params: { id: '2' } }, { params: { id: '3' } } ];}
const { id } = Astro.params;---<h1>{id}</h1>在 SSR 构建中,这可以是与动态路由模式中的路径段匹配的任何值。
---import { getPost } from '../api';
const post = await getPost(Astro.params.id);
// 找不到使用此 ID 的文章if (!post) { Astro.redirect("/404")}---<html> <h1>{post.name}</h1></html>另见:params
Astro.request
段落标题 Astro.request类型:Request
Astro.request 是标准的 Request 对象。它可以用来获取请求的 url、headers、method,甚至是 body。可以使用 new URL(Astro.request.url) 来获得链接对象。
<p>Received a {Astro.request.method} request to "{Astro.request.url}".</p><p>Received request headers: <code>{JSON.stringify(Object.fromEntries(Astro.request.headers))}</code>另见:Astro.url
默认的 output: static 选项中,Astro.request.url 不包含搜索参数,如 ?foo=bar,因为在静态构建中不可能提前确定这些参数。但是在 output: 'server' 模式下,Astro.request.url 可以包含搜索参数,因为它可以从服务器请求中确定。
Astro.response
段落标题 Astro.response类型:ResponseInit & { readonly headers: Headers }
Astro.response 是标准的 ResponseInit 对象,它具有以下结构:
status:响应的状态码,例如200。statusText:响应状态码与之相对应的状态信息,例如OK。headers:一个能让你为响应设置 HTTP 头部的Headers实例。
所以 Astro.response 也用于设置页面响应的 status、statusText 和 headers。
---if(condition) { Astro.response.status = 404; Astro.response.statusText = 'Not found';}---或者设置 header:
---Astro.response.headers.set('Set-Cookie', 'a=b; Path=/;');---Astro.cookies
段落标题 Astro.cookies类型:AstroCookies
astro@1.4.0
Astro.cookies 包含用于在服务端渲染模式下读取和操作 cookie 的工具方法。
get
段落标题 get类型:(key: string, options?: AstroCookieGetOptions) => AstroCookie | undefined
获取 AstroCookie 对象形式的 cookie,该对象包含value和用于将 cookie 转换为非字符串类型的工具方法。
has
段落标题 has类型:(key: string, options?: AstroCookieGetOptions) => boolean
用于判断 cookie 是否存在。如果这个 cookie 已经通过Astro.cookies.set()设置,这将返回 true,否则它将检查 Astro.request 中的 cookies。
set
段落标题 set类型:(key: string, value: string | object, options?: AstroCookieSetOptions) => void
将 cookie key 设置为给定的值。这将试图把 cookie 的值转换为一个字符串。选项提供了设置 cookie 功能的方法,例如 maxAge 或 httpOnly。
delete
段落标题 delete类型:(key: string, options?: AstroCookieDeleteOptions) => void
通过设置过去的到期日期(Unix 时间为 0)使 cookie 失效。
一旦 Cookie 被“删除”(过期),Astro.cookies.has() 将返回 false,Astro.cookies.get() 将返回一个 value 为 undefined 的 AstroCookie。删除 Cookie 时可用的选项包括:domain、path、httpOnly、sameSite 和 secure。
merge
段落标题 merge类型:(cookies: AstroCookies) => void
将新的 AstroCookies 实例合并到当前实例中。任何新的 cookie 将被添加到当前实例中,任何具有相同名称的 cookie 将覆盖现有值。
headers
段落标题 headers类型:() => Iterator<string>
获取将与响应一起发送的 Set-Cookie 的 header 的值。
AstroCookie
段落标题 AstroCookie通过 Astro.cookies.get() 获取 cookie 返回一个 AstroCookie 类型。它具有以下结构。
value
段落标题 value类型:string
cookie 的原始字符串值。
json
段落标题 json类型:() => Record<string, any>
通过 JSON.parse() 解析 cookie 值,返回一个对象。如果 cookie 值不是有效的 JSON,则抛出异常。
number
段落标题 number类型:() => number
将 cookie 值解析为数字。如果不是有效数字,则返回 NaN。
boolean
段落标题 boolean类型:() => boolean
转换 cookie 的值为 boolean 类型。
AstroCookieGetOptions
段落标题 AstroCookieGetOptions
添加于:
astro@4.1.0
获取 cookie 允许通过 AstroCookieGetOptions 接口指定选项:
decode
段落标题 decode类型:(value: string) => string
允许自定义如何将 cookie 反序列化为值。
AstroCookieSetOptions
段落标题 AstroCookieSetOptions
添加于:
astro@4.1.0
通过 Astro.cookies.set() 设置 cookie,允许传入 AstroCookieSetOptions 来自定义 cookie 如何被序列化。
domain
段落标题 domain类型:string
指定域。如果未设置域,则大多数客户端将解释为应用于当前域。
expires
段落标题 expires类型:Date
指定 cookie 过期日期。
httpOnly
段落标题 httpOnly类型:boolean
如果为 true,则客户端将无法访问该 Cookie。
maxAge
段落标题 maxAge类型:number
以秒为单位指定 cookie 有效的时间。
path
段落标题 path类型:string
指定应用 cookie 的域的子路径。
sameSite
段落标题 sameSite类型:boolean | 'lax' | 'none' | 'strict'
指定 SameSite cookie header 的值。
secure
段落标题 secure类型:boolean
如果为 true,则该 Cookie 仅在 https 网站上设置。
encode
段落标题 encode类型:(value: string) => string
允许自定义 cookie 序列化方式。
Astro.redirect()
段落标题 Astro.redirect()类型:(path: string, status?: number) => Response
允许你重定向到另一个页面,并可选地提供一个 HTTP 响应状态码 作为第二个参数。
页面(而不是子组件)必须 return Astro.redirect() 的结果,以便重定向发生。
对于静态生成的网站,这将使用 <meta http-equiv="refresh"> 标签 实现客户端重定向,并且不支持状态码。
使用按需渲染模式时,支持状态码。除非指定其他代码,否则 Astro 将以默认的 HTTP 302 响应状态码实现重定向请求。
以下示例将用户重定向到登录页面:
---import { isLoggedIn } from '../utils';
const cookie = Astro.request.headers.get('cookie');
// 如果用户未登录,则将其重定向到登录页面if (!isLoggedIn(cookie)) { return Astro.redirect('/login');}---Astro.rewrite()
段落标题 Astro.rewrite()类型:(rewritePayload: string | URL | Request) => Promise<Response>
astro@4.13.0
允许你从不同的 URL 或路径提供内容,而不会将浏览器重定向到新页面。
该方法接受字符串、URL 或 Request 作为路径的位置。
使用字符串提供一个明确的路径:
---return Astro.rewrite("/login")---当你需要构造重写的 URL 路径时,使用 URL 类型。以下示例通过从相对路径 "../" 创建一个新的 URL 来呈现页面的父路径:
---return Astro.rewrite(new URL("../", Astro.url))---使用 Request 类型完全控制发送到新路径的 Request。以下示例发送一个请求来渲染父页面,同时提供标头:
---return Astro.rewrite(new Request(new URL("../", Astro.url), { headers: { "x-custom-header": JSON.stringify(Astro.locals.someValue) }}))---Astro.url
段落标题 Astro.url类型:URL
astro@1.0.0-rc
由当前 Astro.request.url 的链接字符串值构造的 URL对象。对于与请求链接的某些属性进行交互很有用,例如 pathname 和 origin。
相当于 new URL(Astro.request.url)。
如果 site 未配置为静态站点或者使用 server 或 hybrid 输出的按需渲染站点,Astro.url 在开发模式下将是 localhost。
<h1>当前链接是:{Astro.url}</h1><h1>当前链接路径名是:{Astro.url.pathname}</h1><h1>当前链接源是:{Astro.url.origin}</h1>你也可以使用 Astro.url 来创建新的链接,并把它作为参数传给 new URL()。
---// 示例:使用你的生产域名构建一个规范的URLconst canonicalURL = new URL(Astro.url.pathname, Astro.site);// 示例:使用你目前的域名构建一个用于 SEO meta 标签的URLconst socialImageURL = new URL('/images/preview.png', Astro.url);---<link rel="canonical" href={canonicalURL} /><meta property="og:image" content={socialImageURL} />Astro.clientAddress
段落标题 Astro.clientAddress类型:string
astro@1.0.0-rc
指定请求的 IP 地址。这个属性只在为 SSR(服务器端渲染)构建时可用,不应该用于静态网站。
---const ip = Astro.clientAddress;---
<div>你的 IP 地址是:<span class="address">{ ip }</span></div>Astro.site
段落标题 Astro.site类型:URL | undefined
Astro.site 返回根据 Astro 配置中的 site 生成的 URL。如果未定义 Astro 配置中的 site,Astro.site 也不会被定义。
Astro.generator
段落标题 Astro.generator类型:string
astro@1.0.0
Astro.generator 是个便捷方法,它可以添加与你当前 Astro 版本一致的 <meta name="generator"> 标签。它遵循的格式是 "Astro v1.x.x"。
<html> <head> <meta name="generator" content={Astro.generator} /> </head> <body> <footer> <p>由 <a href="https://astro.build">{Astro.generator}</a> 构建</p> </footer> </body></html>Astro.slots
段落标题 Astro.slotsAstro.slots 包含修改 Astro 组件插槽的工具函数。
Astro.slots.has()
段落标题 Astro.slots.has()类型:(slotName: string) => boolean
你可以使用 Astro.slots.has() 检查特定插槽名称的内容是否存在。当你想要包装插槽内容,但只想在使用插槽时呈现包装器元素时,这会很有用。
------<slot />
{Astro.slots.has('more') && ( <aside> <h2>More</h2> <slot name="more" /> </aside>)}Astro.slots.render()
段落标题 Astro.slots.render()类型:(slotName: string, args?: any[]) => Promise<string>
你可以使用 Astro.slots.render() 将插槽的内容异步渲染为 HTML 字符串。
---const html = await Astro.slots.render('default');---<Fragment set:html={html} />这是针对高级用例的!在大多数情况下,使用 <slot /> 元素呈现插槽内容会更简单。
Astro.slots.render() 还可以接受第二个参数:一个参数数组,该参数数组将被转发给任何函数子组件。这对于自定义实用程序组件很有用。
举个例子,这个 <Shout /> 组件将它的 message 属性转换为大写,并将其传递给默认插槽:
---const message = Astro.props.message.toUpperCase();let html = '';if (Astro.slots.has('default')) { html = await Astro.slots.render('default', [message]);}---<Fragment set:html={html} />作为 <Shout /> 的子级传递的回调函数将会接收到大写的 message 参数:
---import Shout from "../components/Shout.astro";---<Shout message="slots!"> {(message) => <div>{message}</div>}</Shout>
<!-- 渲染成 <div>SLOTS!</div> -->回调函数可以传递给带有 slot 属性并包装着 HTML 元素标签的具名插槽。这个元素仅用于将回调传递给具名插槽,而不会被渲染到页面上。
<Shout message="slots!"> <fragment slot="message"> {(message) => <div>{message}</div>} </fragment></Shout>使用标准的 HTML 元素作为包装标签,或者使用任何小写标签(例如 <fragment> 而不是 <Fragment />),这些标签不会被解释为组件。不要使用 HTML 的 <slot> 元素,因为它会被解释为 Astro 插槽。
Astro.self
段落标题 Astro.selfAstro.self 允许 Astro 组件被递归调用。这使得你可以通过在组件模板中使用 <Astro.self> 从自身内部渲染 Astro 组件。这对遍历大型数据存储和嵌套数据结构很有帮助。
---const { items } = Astro.props;---<ul class="nested-list"> {items.map((item) => ( <li> <!-- 如果有嵌套的数据结构,将渲染 `<Astro.self>` --> <!-- 并可以通过递归调用来传递参数 --> {Array.isArray(item) ? ( <Astro.self items={item} /> ) : ( item )} </li> ))}</ul>然后,这个组件可以这样用:
---import NestedList from './NestedList.astro';---<NestedList items={['A', ['B', 'C'], 'D']} />之后将会渲染这样的 HTML:
<ul class="nested-list"> <li>A</li> <li> <ul class="nested-list"> <li>B</li> <li>C</li> </ul> </li> <li>D</li></ul>Astro.locals
段落标题 Astro.locals
添加于:
astro@2.4.0
Astro.locals 是一个对象,包含来自中间件的 context.locals对象的任何值。使用该对象可访问中间件在你的 .astro 文件中返回的数据。
---const title = Astro.locals.welcomeTitle();const orders = Array.from(Astro.locals.orders.entries());---<h1>{title}</h1><ul> {orders.map(order => { return <li>{ /* 每单都有收获 */ }</li> })}</ul>Astro.preferredLocale
段落标题 Astro.preferredLocale类型:string | undefined
astro@3.5.0
Astro.preferredLocale 是一个代表当前用户的首选语言环境的计算出的值。
它是通过检查 i18n.locales 数组中配置的语言环境和用户浏览器通过头部 Accept-Language 指定的语言环境来计算的。如果不存在匹配项则该值为 undefined。
这个属性只在为 SSR(服务器端渲染)构建时可用,不应该用于静态网站。
Astro.preferredLocaleList
段落标题 Astro.preferredLocaleList类型:string[] | undefined
astro@3.5.0
Astro.preferredLocaleList 是一个同时被浏览器请求并且你的网站也支持的语言环境的数组。它是一个由你的网站和你的访客共同支持的语言环境的列表。
如果浏览器请求的语言环境没有在你的网站中被支持,那么该值为 []:你不支持你的访客的任何首选语言环境。
如果浏览器没有指定任何首选语言环境,那么该值将是 i18n.locales:你支持的所有语言环境都将被同等视为访客倾向的语言环境。
这个属性只在为 SSR(服务器端渲染)构建时可用,不应该用于静态网站。
Astro.currentLocale
段落标题 Astro.currentLocale类型:string | undefined
astro@3.5.6
从当前 URL 使用你的 locales 配置中指定的语法计算出的语言环境。如果 URL 不包含 /[locale]/ 前缀,则该值将默认为 i18n.defaultLocale。
Astro.getActionResult()
段落标题 Astro.getActionResult()类型:(action: TAction) => ActionReturnType<TAction> | undefined
astro@4.15.0
Astro.getActionResult() 是一个返回 Action 提交结果的函数。它接受一个 Action 函数作为参数(例如 actions.logout),当接收到提交时返回一个 data 或 error 对象。否则,它将返回 undefined。
---import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.logout);---
<form action={actions.logout}> <button type="submit">退出登录</button></form>{result?.error && <p>退出登录失败。请再试一次。</p>}Astro.callAction()
段落标题 Astro.callAction()
添加于:
astro@4.15.0
Astro.callAction() 是一个直接从你的 Astro 组件中调用 Action 处理程序的函数。它接受一个 Action 函数作为第一个参数(例如 actions.logout),以及该 Action 接收的任何输入作为第二个参数。它返回 Action 的结果作为 Promise。
---import { actions } from 'astro:actions';
const { data, error } = await Astro.callAction(actions.logout, { userId: '123' });---端点上下文
段落标题 端点上下文端点函数接收一个上下文对象作为第一个参数。它与许多 Astro 全局属性相似。
import type { APIContext } from 'astro';
export function GET(context: APIContext) { // ...}context.params
段落标题 context.paramscontext.params 是一个对象,其中包含与此请求匹配的动态路由段的值。
在静态构建中,这将是用于预渲染动态路由的 getStaticPaths() 返回的 params。
在 SSR 构建中,这可以是与动态路由模式中的路径段匹配的任何值。
import type { APIContext } from 'astro';
export function getStaticPaths() { return [ { params: { id: '1' } }, { params: { id: '2' } }, { params: { id: '3' } } ];}
export function GET({ params }: APIContext) { return new Response( JSON.stringify({ id: params.id }), );}另见:params
context.props
段落标题 context.props
添加于:
astro@1.5.0
context.props 是一个对象,其中包含从 getStaticPaths() 传递的任何 props。由于在为 SSR 构建时不使用 getStaticPaths(),因此 context.props 仅在静态构建中可用。
import type { APIContext } from 'astro';
export function getStaticPaths() { return [ { params: { id: '1' }, props: { author: 'Blu' } }, { params: { id: '2' }, props: { author: 'Erika' } }, { params: { id: '3' }, props: { author: 'Matthew' } } ];}
export function GET({ props }: APIContext) { return new Response( JSON.stringify({ author: props.author }), );}另见:通过props传递数据
context.request
段落标题 context.request类型:Request
一个标准的 Request 对象。它可以用来获取请求的 url、headers、method 甚至是 body。
import type { APIContext } from 'astro';
export function GET({ request }: APIContext) { return new Response(`Hello ${request.url}`);}context.cookies
段落标题 context.cookies类型:AstroCookies
context.cookies 包含用于读取和操作 cookie 的工具。
context.url
段落标题 context.url类型:URL
astro@1.5.0
context.url 是一个 URL 对象,它是从当前 context.request.url URL 字符串值构造的。
另见:Astro.url
context.clientAddress
段落标题 context.clientAddress类型:string
astro@1.5.0
指定请求的 IP 地址。此属性仅在构建 SSR(服务器端渲染)时可用,不应用于静态站点。
import type { APIContext } from 'astro';
export function GET({ clientAddress }: APIContext) { return new Response(`Your IP address is: ${clientAddress}`);}context.site
段落标题 context.site类型:URL | undefined
astro@1.5.0
context.site 返回一个由 Astro 配置中的 site 生成的 URL。如果未定义,则将返回从 localhost 生成的 URL。
另见:Astro.site
context.generator
段落标题 context.generator类型:string
astro@1.5.0
context.generator 是一个方便的方法,用于指示项目正在运行的 Astro 版本。它遵循 "Astro v1.x.x" 的格式。
import type { APIContext } from 'astro';
export function GET({ generator, site }: APIContext) { const body = JSON.stringify({ generator, site }); return new Response(body);}context.redirect()
段落标题 context.redirect()类型:(path: string, status?: number) => Response
astro@1.5.0
context.redirect() 返回一个 Response 对象,允许你重定向到另一个页面。此函数仅在构建 SSR(服务器端渲染)时可用,不应用于静态站点。
import type { APIContext } from 'astro';
export function GET({ redirect }: APIContext) { return redirect('/login', 302);}context.rewrite()
段落标题 context.rewrite()类型:(rewritePayload: string | URL | Request) => Promise<Response>
astro@4.13.0
允许你从不同的 URL 或路径提供内容,而不会将浏览器重定向到新页面。
该方法接受字符串、URL 或 Request 作为路径的位置。
使用字符串提供一个明确的路径:
import type { APIContext } from 'astro';
export function GET({ rewrite }: APIContext) { return rewrite('/login');}当你需要构造重写的 URL 路径时,使用 URL 类型。以下示例通过从相对路径 "../" 创建一个新的 URL 来呈现页面的父路径:
import type { APIContext } from 'astro';
export function GET({ rewrite }: APIContext) { return rewrite(new URL("../", Astro.url));}使用 Request 类型完全控制发送到新路径的 Request。以下示例发送一个请求来渲染父页面,同时提供标头:
import type { APIContext } from 'astro';
export function GET({ rewrite }: APIContext) { return rewrite(new Request(new URL("../", Astro.url), { headers: { "x-custom-header": JSON.stringify(Astro.locals.someValue) } }));}context.locals
段落标题 context.locals
添加于:
astro@2.4.0
context.locals 是一个对象,用于在请求的生命周期内存储和访问任意信息。
中间件函数可以读写context.locals的值:
import type { MiddlewareHandler } from 'astro';
export const onRequest: MiddlewareHandler = ({ locals }, next) => { if (!locals.title) { locals.title = "Default Title"; } return next();}API 端点只能从 context.locals中读取信息:
import type { APIContext } from 'astro';
export function get({ locals }: APIContext) { return new Response(locals.title); // "默认标题"}另见:Astro.locals
context.getActionResult()
段落标题 context.getActionResult()类型: (action: TAction) => ActionReturnType<TAction> | undefined
astro@4.15.0
context.getActionResult() 是一个函数,用于从你的 Astro 组件中返回 Action 提交结果。它接受一个 Action 函数作为参数(例如 actions.logout),当接收到提交时返回一个 data 或 error 对象。否则,它将返回 undefined。
context.callAction()
段落标题 context.callAction()
添加于:
astro@4.15.0
context.callAction() 是一个直接从你的 Astro 组件中调用 Action 处理程序的函数。它接受一个 Action 函数作为第一个参数(例如 actions.logout),以及该 Action 接收的任何输入作为第二个参数。它返回 Action 的结果作为 Promise。
getStaticPaths()
段落标题 getStaticPaths()类型:(options: GetStaticPathsOptions) => Promise<GetStaticPathsResult> | GetStaticPathsResult
如果页面在文件名中使用动态参数,该组件将需要导出一个 getStaticPaths() 函数。
必须要有该函数,因为 Astro 是静态站点生成器。这意味着整个网站是预构建的。如果 Astro 不知道在构建时生成什么页面,你的用户在访问你的网站时就看不到它。
---export async function getStaticPaths() { return [ { params: { /* 必需 */ }, props: { /* 可选 */ } }, { params: { ... } }, { params: { ... } }, // ... ];}---<!-- 你的 HTML 模板在这里 -->getStaticPaths() 函数应该返回对象数组,以确定哪些路径会被 Astro 预渲染。
使用 TypeScript 时,请使用 GetStaticPaths 类型工具来确保对 params 和 props 进行类型安全的获取。
getStaticPaths() 函数会在任何页面加载之前,在它自己的隔离范围内执行一次。因此,除了文件导入之外,你不能从它的父作用域中引用任何东西。如果你违反了这个要求,编译器会发出警告。
params
段落标题 params每个返回对象的 params 键都会告诉 Astro 要构建什么路由。返回参数必须映射到你的组件文件路径中定义的动态参数和其余参数。
params 被编码到链接中,所以只能由字符串作为值。每个 params 对象的值必须与页面名称中使用的参数一致。
比如说有 src/pages/posts/[id].astro 页面。如果你从这个页面导出 getStaticPaths 并返回以下的路由:
---export async function getStaticPaths() { return [ { params: { id: '1' } }, { params: { id: '2' } }, { params: { id: '3' } } ];}
const { id } = Astro.params;---<h1>{id}</h1>然后 Astro 会在构建时静态地生成 posts/1、posts/2 和 posts/3。
通过 props 传递数据
段落标题 通过 props 传递数据为了给每个生成的页面传递额外的数据,你也可以在每个返回的路径对象上设置 props 值。与 params 不同的是,props 没有被编码到链接中,所以并不局限于字符串。
例如,假设你根据从远程 API 获取的数据来生成页面。你可以将完整的数据对象传递给 getStaticPaths 中的页面组件。
---export async function getStaticPaths() { const data = await fetch('...').then(response => response.json());
return data.map((post) => { return { params: { id: post.id }, props: { post }, }; });}
const { id } = Astro.params;const { post } = Astro.props;---<h1>{id}: {post.name}</h1>你也可以传递普通数组,这在生成或缓存已知路径列表时可能会有帮助。
---export async function getStaticPaths() { const posts = [ {id: '1', category: "astro", title: "API Reference"}, {id: '2', category: "react", title: "Creating a React Counter!"} ]; return posts.map((post) => { return { params: { id: post.id }, props: { post } }; });}const {id} = Astro.params;const {post} = Astro.props;---<body> <h1>{id}: {post.title}</h1> <h2>Category: {post.category}</h2></body>然后 Astro 将在构建时使用 pages/posts/[id].astro 中的页面组件静态地生成 posts/1 和 posts/2。页面可以使用 Astro.props 引用这些数据。
paginate()
段落标题 paginate()分页是 Astro 通过 paginate() 函数原生支持网站的常见用例。paginate() 将自动生成数组,从getStaticPaths()返回,为分页集合的每个页面创建一个 URL。页面编号将作为参数传递,而页面数据将作为page道具传递。
export async function getStaticPaths({ paginate }) { // 用 fetch()、Astro.glob() 等加载你的数据 const response = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=150`); const result = await response.json(); const allPokemon = result.results;
// 返回包含分页的所有帖子的路由集合 return paginate(allPokemon, { pageSize: 10 });}
// 如果设置正确,现在页面已经具备了渲染单页所需的一切参数(见下一节)。const { page } = Astro.props;paginate() 函数具有以下参数:
data- 数组,包含了传递给paginate()函数的页面数据片段options- 具有以下属性的可选对象:pageSize- 每页显示的项目数(默认为10)params- 用于创建动态路由的附加参数props- 在每个页面上可用的附加属性
paginate():假定文件名为 [page].astro 或 [...page].astro。page 参数将是链接中的页数。
/posts/[page].astro:会产生/posts/1、/posts/2、/posts/3等链接。/posts/[...page].astro:将产生/posts、/posts/2/posts/3等链接。
page 分页参数
段落标题 page 分页参数类型: Page<TData>
分页会给每个渲染的页面传递 page 参数,代表分页集合中的单页数据。这包括你分页的数据(page.data)以及该页的元数据(page.url、page.start、page.end、page.total 等)。这些元数据对诸如“下一页”按钮或“显示 100 个中前十个”的信息很有用。
page.data
段落标题 page.data类型: Array<TData>
从 paginate() 函数中返回当前页面数据的数组。
page.start
段落标题 page.start类型:number
当前页第一个项目的索引,从 0 开始(例如,如果 pageSize: 25,第一页该值未 0,第二页为25,以此类推)。
page.end
段落标题 page.end类型:number
当前页面最后一条数据的索引。
page.size
段落标题 page.size类型:number
默认值:10
每个页面有多少条数据。
page.total
段落标题 page.total类型:number
所有数据的总数量。
page.currentPage
段落标题 page.currentPage类型:number
当前页码,从 1 开始。
page.lastPage
段落标题 page.lastPage类型:number
总页数。
page.url.current
段落标题 page.url.current类型:string
获取当前页面的链接(对规范链接很有用)。
page.url.prev
段落标题 page.url.prev类型:string | undefined
获取上一页链接(如果在首页,将是undefined)。如果为 base 设置了值,那么需要将 base 路径拼接到链接前面。
page.url.next
段落标题 page.url.next类型:string | undefined
获取下一页链接(如果没有更多的页面,将是undefined)。如果为 base 设置了值,那么需要将 base 路径拼接到链接前面。
page.url.first
段落标题 page.url.first类型:string | undefined
astro@4.12.0
获取第一页链接(如果在首页,将是undefined)。 如果为 base 设置了值,那么需要将 base 路径拼接到链接前面。
page.url.last
段落标题 page.url.last类型:string | undefined
astro@4.12.0
获取最后一页链接(如果在最后一页,将是undefined)。如果为 base 设置了值,那么需要将 base 路径拼接到链接前面。
import.meta
段落标题 import.meta所有 ESM 模块都包含 import.meta 属性。Astro 基于 Vite 增加了 import.meta.env。
import.meta.env.SSR 可以用来了解何时在服务器渲染。有时你可能想要不同的逻辑,例如,某个组件应该只在客户端渲染:
export default function () { return import.meta.env.SSR ? <div class="spinner"></div> : <FancyComponent />;}