> Leaf UI 0.6.0 · Package: @ifhover/leaf-ui · Source: b30c3d3a8fa9c5e15d0d0522cebfbd33f60c6b06
> Browser documentation: https://ifhover.github.io/leaf-ui/v/0.6.0/components/message.html

> For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt.

# Message 消息提示

以短暂提示反馈操作结果。

## 入口配置一次

在应用入口使用 `ConfigProvider`，它会自动管理消息。页面和业务组件调用 `useMessage` 后即可显示消息。

```tsx
import { ConfigProvider } from '@ifhover/leaf-ui';

export function Root() {
  return <ConfigProvider><App /></ConfigProvider>;
}
```

已经使用 `ConfigProvider` 的应用无需新增配置。`useMessage` 应在它的子组件中调用，返回的 `message` 也可以作为参数传给业务方法。

## 消息与更新


异步保存提示错误成功警告清空消息

basic.tsx

复制代码

```tsx lineNumbers file="../../src/examples/message/basic.tsx"
import { Button, Flex, useMessage } from '@ifhover/leaf-ui';

export function MessageBasic() {
  const { message } = useMessage();
  async function save() {
    const key = message.loading('正在保存');
    await new Promise((resolve) => setTimeout(resolve, 1200));
    message.open({ key, type: 'success', content: '保存成功', duration: 3, closable: true });
  }
  return (
    <Flex gap="md" align="center" wrap justify="center">
      <Button onClick={save}>异步保存</Button>
      <Button variant="outline" onClick={() => message.info('一条消息提示')}>
        提示
      </Button>
      <Button danger variant="outline" onClick={() => message.error('操作失败，请重试')}>
        错误
      </Button>
      <Button variant="outline" onClick={() => message.success('操作成功')}>
        成功
      </Button>
      <Button variant="outline" onClick={() => message.warning('请检查输入内容')}>
        警告
      </Button>
      <Button variant="ghost" onClick={() => message.close()}>
        清空消息
      </Button>
    </Flex>
  );
}
```

展开代码

## 跨组件共享

下面两个按钮来自不同子组件。相同的 `key` 可以更新同一条消息，页面切换后也能继续反馈操作结果。


开始发布在另一个组件更新结果

shared.tsx

复制代码

```tsx lineNumbers file="../../src/examples/message/shared.tsx"
import { Button, Flex, useMessage } from '@ifhover/leaf-ui';

function PublishAction() {
  const { message } = useMessage();
  return (
    <Button
      variant="outline"
      onClick={() =>
        message.open({ key: 'shared-publish', type: 'loading', content: '正在发布项目' })
      }
    >
      开始发布
    </Button>
  );
}

function PublishResult() {
  const { message } = useMessage();
  return (
    <Button
      onClick={() =>
        message.open({
          key: 'shared-publish',
          type: 'success',
          content: '项目已发布',
          duration: 3,
          closable: true,
        })
      }
    >
      在另一个组件更新结果
    </Button>
  );
}

export function MessageShared() {
  return (
    <Flex gap="md" align="center" wrap justify="center">
      <PublishAction />
      <PublishResult />
    </Flex>
  );
}
```

展开代码

## 多条消息

消息关闭时，后续消息会平滑上移。不同高度的内容会按照实际占用空间收起。


连续显示三条消息

stack.tsx

复制代码

```tsx lineNumbers file="../../src/examples/message/stack.tsx"
import { Button, useMessage } from '@ifhover/leaf-ui';

export function MessageStack() {
  const { message } = useMessage();
  return (
    <Button
      variant="outline"
      onClick={() => {
        message.close();
        message.open({ key: 'stack-first', content: '第一条消息将在一秒后消失', duration: 1 });
        message.open({
          key: 'stack-second',
          content: '后续消息会平滑上移',
          duration: 5,
          closable: true,
        });
        message.open({
          key: 'stack-third',
          content: '较长的消息内容也会根据实际高度自然收起，不会跳到新的位置。',
          type: 'success',
          duration: 7,
          closable: true,
        });
      }}
    >
      连续显示三条消息
    </Button>
  );
}
```

展开代码

## useMessage API

| 属性        | 类型                          | 默认值 | 说明          |
| --------- | --------------------------- | --- | ----------- |
| `message` | [`MessageApi`](#messageapi) | —   | 调用入口托管的消息队列 |

## MessageProvider API

未使用 `ConfigProvider` 时，可在入口使用 `MessageProvider`。显式添加它也可以为某个区域建立独立的消息队列。

```tsx
import { MessageProvider } from '@ifhover/leaf-ui';

export function Root() {
  return <MessageProvider><App /></MessageProvider>;
}
```

| 属性         | 类型          | 默认值 | 说明         |
| ---------- | ----------- | --- | ---------- |
| `children` | `ReactNode` | —   | 共用此消息队列的组件 |

## MessageApi

| 属性                                 | 类型                                                       | 默认值 | 说明                 |
| ---------------------------------- | -------------------------------------------------------- | --- | ------------------ |
| `open`                             | [`(options: MessageOptions) => string`](#messageoptions) | —   | 创建或按 key 更新，返回 key |
| `success / info / warning / error` | `(content: ReactNode, duration?: number) => string`      | —   | 快捷显示对应类型           |
| `loading`                          | `(content: ReactNode) => string`                         | —   | 持续加载消息，返回 key      |
| `close`                            | `(key?: string) => void`                                 | —   | 关闭指定消息，无 key 时关闭全部 |

## MessageOptions

| 属性         | 类型                                                         | 默认值      | 说明                          |
| ---------- | ---------------------------------------------------------- | -------- | --------------------------- |
| `key`      | `string`                                                   | 自动生成     | 相同 key 更新现有消息               |
| `content`  | `ReactNode`                                                | 必填       | 消息内容                        |
| `type`     | `'success' \| 'info' \| 'warning' \| 'error' \| 'loading'` | `'info'` | 消息类型                        |
| `duration` | `number`                                                   | `3`      | 自动关闭秒数；0 不自动关闭；loading 默认 0 |
| `closable` | `boolean`                                                  | `false`  | 展示关闭按钮                      |
| `onClose`  | `() => void`                                               | —        | 开始关闭时触发一次                   |

## Message API

| 属性                     | 类型                                                         | 默认值      | 说明                     |
| ---------------------- | ---------------------------------------------------------- | -------- | ---------------------- |
| `open`                 | `boolean`                                                  | 必填       | 受控显示状态                 |
| `content`              | `ReactNode`                                                | 必填       | 消息内容                   |
| `type`                 | `'success' \| 'info' \| 'warning' \| 'error' \| 'loading'` | `'info'` | 消息类型                   |
| `duration`             | `number`                                                   | `3`      | 秒数；0 持续显示；loading 默认 0 |
| `closable`             | `boolean`                                                  | `false`  | 关闭按钮                   |
| `onClose / afterClose` | `() => void`                                               | —        | 请求关闭 / 动画完成            |

## 类型

定义组件属性或组装变量时可导入相关类型。

```ts
import type { MessageProps, MessageOptions, MessageApi, MessageProviderProps } from '@ifhover/leaf-ui';
```

## 使用说明

推荐通过 `useMessage` 使用，同一 `key` 可以把加载消息更新为结果。鼠标停留或焦点位于消息中时暂停计时，离开后按剩余时间继续。

同一入口下的组件共享队列；`close()` 关闭该队列的全部消息，`close(key)` 仅关闭指定消息。嵌套的 `ConfigProvider` 沿用同一个队列，每条消息仍使用调用组件所在区域的主题和语言。

调用组件卸载后，已有消息继续按时关闭，异步任务也可通过同一 `message` 更新结果。入口 provider 卸载后，其消息和计时器一起清理。不同 React 应用及 SSR 请求各自拥有队列。

也支持直接渲染 `Message`；收到 `onClose` 后由应用设置 `open=false`。
