---
title: Toast 提示
description: 在屏幕一角堆叠显示的短暂通知
category: Feedback
status: beta
since: 0.3.4
tags: [toast, feedback, status]
syncStatus: reviewed
verified: true
---

## 用法

### 基础
挂载一个 `TxToastHost`，再调用 `toast()`；悬停这摞通知会展开并暂停所有倒计时。
:::TuffDemoWrapper{demo="ToastToastDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { toast } from '@talex-touch/tuffex/utils'
  </script>

  <template>
    <TxToastHost position="bottom-right" />
    <TxButton @click="toast({ title: 'Saved', description: 'Your changes have been saved.' })">
      Show toast
    </TxButton>
    <TxButton @click="toast({ title: 'Success', description: 'Done', variant: 'success' })">
      Success
    </TxButton>
    <TxButton @click="toast({ title: '已删除 1 项', action: { label: '撤销', onClick: restore } })">
      With action
    </TxButton>
  </template>
---
:::

### 后台反馈中心
Toast 负责短反馈，`TxTooltip` 解释动作，`TxLoadingOverlay` 阻断局部刷新，`TxSpinner` 承担行内等待。
:::TuffDemoWrapper{demo="ComponentsFeedbackTaskCenterDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { clearToasts, toast } from '@talex-touch/tuffex/utils'

  function showFeedbackToast() {
    // 稳定 id + duration: 0：同一状态替换上一条，而不是继续堆叠
    toast({ id: 'nexus-feedback-task-center', title: '同步任务已排队', variant: 'warning', duration: 0 })
  }
  </script>

  <template>
    <TxToastHost />
    <TxTooltip content="Tooltip 只解释当前动作。">
      <TxButton @click="showFeedbackToast">发送提示</TxButton>
    </TxTooltip>
    <TxLoadingOverlay :loading="syncing" text="正在刷新任务队列…">
      <TxSpinner :size="16" />
    </TxLoadingOverlay>
    <TxButton variant="ghost" @click="clearToasts()">清空提示</TxButton>
  </template>
---
:::

### 最佳实践

- 只在应用根部附近挂一个 host，用 `position` 控制方位；多余的 host 不会绘制，但仍有一个容器和一条开发告警。
- 任务、保存、同步、重试类通知用稳定的 `id`，让重复的状态更新替换上一条。
- 常驻状态用稳定 `id` 加 `duration: 0`；离开所属页面或任务结束时清理。
- 描述保持简短；长进度、带恢复动作的错误或表单放到面板、抽屉或页面。
- 关键失败与长任务另配常驻可见的文案或页面状态。

## API 参考

### TxToastHost 属性

| 属性名 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `position` | `'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right'` | `'bottom-right'` | 这摞通知从哪个角或哪条边的中间长出。 |
| `visibleToasts` | `number` | `3` | 同时可见的条数；其余透明排队，等前面的离场再补位。 |
| `expand` | `boolean` | `false` | 常驻展开，指针离开也不收拢。 |
| `gap` | `number` | `14` | 通知间距（px），也是收拢时露出的边。 |
| `offset` | `number` | `16` | 与视口边缘的距离。 |
| `swipeToDismiss` | `boolean` | `true` | 允许把通知朝它所靠的边甩出去。 |

### toast(options)

从 `@talex-touch/tuffex/utils` 导入：

:::TuffCodeBlock{lang="ts"}
---
code: |
  toast({
    id?: string
    title?: string
    description?: string
    variant?: 'default' | 'info' | 'success' | 'warning' | 'danger'
    duration?: number // 默认 2600，0 = 不自动关闭
    action?: {
      label: string
      onClick?: (id: string) => void
      dismiss?: boolean // 默认 true —— onClick 执行完就关掉这条
    }
  }): string
---
:::

### dismissToast / clearToasts

:::TuffCodeBlock{lang="ts"}
---
code: |
  import { clearToasts, dismissToast, toast } from '@talex-touch/tuffex/utils'

  const id = toast({ title: '已排队', duration: 0 })
  dismissToast(id)
  clearToasts()
---
:::

### pauseToasts / resumeToasts / toastsPaused

`TxToastHost` 在指针或焦点进入时自行调用；只在需要另外按住这摞通知时（如对话框盖在上面）手动调用。

:::TuffCodeBlock{lang="ts"}
---
code: |
  import { pauseToasts, resumeToasts, toastsPaused } from '@talex-touch/tuffex/utils'

  pauseToasts()   // 所有倒计时就地冻结；可重复调用
  toastsPaused()  // => true
  resumeToasts()  // 每条从剩下的时间继续，而不是重新从头计时
---
:::

## 概述

- Host teleport 到 `body`，是带 `aria-label="Notifications"` 的 `role="region"` 与 polite live region；`danger` 升级为 `role="alert"`，每条都有名为 `Dismiss notification` 的关闭按钮。
- `toast()` 返回 id；相同 `id` 替换现有 toast 并按新的 `duration` 重新计时；`duration: 0` 一直显示，直到 `dismissToast(id)` 或 `clearToasts()`。
- 最新一条在最前，后面每条后退 `gap` 像素并缩小 5%；收拢时只有最前一条接收指针，host 的空白处可以点穿。
- 指针或键盘焦点进入时展开并调用 `pauseToasts()`，离开时收拢并调用 `resumeToasts()`。
- 朝所靠的边拖动超过 45px 即关闭，甩动速度超过 0.32px/ms 时 12px 即可；反向拖动只移动五分之一并回弹，从按钮开始的拖动让给按钮。
- 只有第一个挂载的 host 绘制，之后的 host 只渲染空容器以保证 hydrate，并在开发构建下告警；持有者卸载后由下一个接手，通知在挂载后的下一个 tick 出现。

## 技术实现

- 通知沿所在位置的轴向进出（0.4s），减少动态效果时只变透明度；每次调用都经共享 z-index manager 提升 host 层级。
- 工具函数在 `packages/tuffex/packages/utils/toast.ts`，单 host 认领在 `src/toast/src/host-registry.ts`。
- 源码：`packages/tuffex/packages/components/src/toast/`。

<TuffDocSourceLink />
