链接预览

编辑页面

了解在使用 Expo Router 时,如何在 iOS 上为你的链接添加预览。


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

重要 链接预览是仅限 iOS 的功能,适用于 SDK 54 及更高版本。

链接预览(也称为“Peek and Pop”)是 iOS 上常用的一项功能,用于向用户显示某个链接所对应页面的预览弹窗。 本指南将向你展示如何为你的应用在 iOS 上添加并自定义链接预览。

如果你的应用中有一个链接,你可以通过将链接内容替换为 Link.Trigger 并为其添加 Link.Preview 组件来添加链接预览。这样会创建该链接指向页面的预览。

import { Link } from 'expo-router'; export default function Page() { return ( <Link href="/about"> <Link.Trigger>关于</Link.Trigger> <Link.Preview /> </Link> ); }

自定义链接预览

默认情况下,链接预览会以完整页面快照的形式渲染。你可以通过多种方式来自定义这一行为。

自定义大小

你可以使用 widthheight 来建议一个首选预览大小。系统会考虑这些偏好,但可能会根据可用空间或平台行为进行覆盖。

<Link href="..."> <Link.Trigger>内容</Link.Trigger> <Link.Preview style={{ width: 300, height: 200 }} /> </Link>

以下示例展示了 iOS 上自定义大小的链接预览:

自定义预览

如果你不想显示默认预览,可以通过 children 向 Link.Preview 组件传入自定义内容。这个自定义内容将替换链接目标的默认预览。

export default function Page() { const [imageSize, setImageSize] = useState({ width: 0, height: 0 }); const { width } = useWindowDimensions(); const previewHeight = (width / imageSize.width) * imageSize.height; return ( <Link href="/about"> <Link.Trigger>关于</Link.Trigger> <Link.Trigger>内容</Link.Trigger> <Link.Preview style={{ width, height: previewHeight }}> <Image onLoad={e => setImageSize(e.nativeEvent.source)} source={source} style={{ width: '100%', height: '100%' }} /> </Link.Preview> </Link> ); }

以下示例展示了 iOS 上的自定义链接预览:

菜单

要在预览旁边渲染上下文菜单,请添加一个带有 Link.MenuAction 子元素的 Link.Menu

<Link href="/about"> <Link.Trigger>关于</Link.Trigger> <Link.Menu> <Link.MenuAction title="分享" icon="square.and.arrow.up" onPress={handleSharePress} /> <Link.MenuAction title="阻止" icon="nosign" destructive onPress={handleBlockPress} /> </Link.Menu> </Link>

以下示例展示了 iOS 上的自定义链接预览:

图标

你可以使用 SF Symbols 为每个菜单操作指定一个图标。

<Link href="/about"> <Link.Trigger>关于</Link.Trigger> <Link.Menu> <Link.MenuAction title="分享" icon="square.and.arrow.up" onPress={handleSharePress} /> <Link.MenuAction title="阻止" icon="nosign" onPress={handleBlockPress} /> <Link.MenuAction title="关注" icon="person.crop.circle.badge.plus" onPress={handleFollowPress} /> <Link.MenuAction title="复制" icon="doc.on.doc" onPress={handleCopyPress} /> </Link.Menu> </Link>

以下示例展示了 iOS 上带有四个元素的上下文菜单,每个元素都使用不同的图标:

嵌套菜单

你可以通过将一个 Link.Menu 放入另一个菜单中来嵌套菜单:

<Link href="..."> <Link.Trigger>关于</Link.Trigger> <Link.Menu> <Link.MenuAction title="分享" icon="square.and.arrow.up" onPress={() => {}} /> <Link.Menu title="更多" icon="ellipsis"> <Link.MenuAction title="复制" icon="doc.on.doc" onPress={() => {}} /> <Link.MenuAction title="删除" icon="trash" destructive onPress={() => {}} /> </Link.Menu> </Link.Menu> </Link>

以下示例展示了 iOS 上的嵌套上下文菜单:

更多自定义选项

要了解所有可用的自定义选项,请查看 Link.MenuAction 的 API 文档。

检测组件是否处于预览中

如果你正在构建一个可能在预览中渲染的组件,可以使用 useIsPreview() Hook 来相应地调整其行为:

function MyComponent() { // 如果组件/屏幕正在预览中渲染,这里将为 true const isInsidePreview = useIsPreview(); return isInsidePreview ? <Text>在预览中</Text> : <Text>我在预览之外</Text>; }

已知限制

不支持 replace

将链接预览与 replace 模式一起使用目前不支持。预览只能与默认的 push 导航模式一起使用。

JavaScript 标签页和槽位

在 JavaScript 标签页(而非原生标签页)或 Slot 中导航时,预览过渡动画可能会显得卡顿。这是因为 React 的渲染存在延迟,而原生预览动画会立即开始。为避免此问题,请使用原生标签页和栈导航器。

缺少 Link.Trigger

如果你渲染了带有预览或上下文菜单的 Link,但没有 Link.Trigger,则会抛出异常。如果在使用预览模式时,你将任何非 Link.* 组件直接放在 Link 内,也会出现同样的情况。

使用 asChild prop 时存在多个 Link.Trigger 子元素

当使用带有 asChildLink 时,你只能为 Link.Trigger 指定一个子元素。onPress 事件只会转发给该子元素。

在预览打开时更改 href

在预览打开时动态更改 href prop 的路径不支持。你只能动态修改查询参数。