☰
element-react Notification 通知组件指南:选项、类型方法与源码实现解析
2026/10/14 15:54:16 网站建设 项目流程
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】element-react

Element UI

项目地址:https://gitcode.com/gh_mirrors/el/element-react
点击查看免费下载

本篇基于 element-react 官方文档 Notification 组件说明,系统讲解 Notification 通知栏的调用方式、全部选项参数与类型化快捷方法,并结合同仓库的 NotificationCenter 入口、Notification 视图组件 与 TypeScript 类型声明,说明自动关闭计时、堆叠定位与实例回收等底层机制,帮助你在 React 项目中正确接入并排查通知栏行为。

一、Notification 是一个全局方法,而不是 JSX 组件

与 Button、Table 等可直接在 JSX 中声明的组件不同,Notification以命令式方法的形式对外暴露。单独引入方式如下(对应文档Local import一节):

import { Notification } from 'element-react';

引入后直接调用Notification(options),同时也为每种类型注册了方法,例如Notification.success(options)。

从源码结构看,这一"方法即组件"的设计由三个文件协作完成:

  • src/index.js 中导出Notification:export { default as Notification } from './notification';
  • src/notification/index.js 实际默认导出的并不是视图组件,而是一个名为NotificationCenter的工厂函数:export default NotificationCenter;
  • 视图组件 src/notification/Notification.jsx 只被NotificationCenter在内部用于React.createElement,用户无需也不应直接渲染它。

文档站本身的演示页 site/pages/notification/index.jsx 也只是把本文档 Markdown 渲染为示例页面,::: demo代码块由文档站运行时执行。

调用即挂载:DOM 级渲染流程

阅读 NotificationCenter.jsx 可以看到完整的命令式流程:

  1. document.createElement('div')创建一个临时挂载点并appendChild到document.body;
  2. 若传入的参数是字符串或合法的 React Element,则自动包装为{ message: props };
  3. 若第二个参数type存在,则写入props.type;
  4. 计算props.top(见下文堆叠机制),随后React.createElement(Notification, ...)并ReactDOM.render(element, div)独立渲染;
  5. 通知关闭动画结束后,willUnmount回调将临时div从body中移除。

这也解释了为什么文档示例代码都写在open()之类的普通方法里,而不是render()中:每次调用都会产生一棵独立于组件树的渲染子树。

二、基本用法:title、message 与自动关闭时长

Notification接收一个 options 字面量参数,最简情况下只需设置title与message两个字段,分别作为通知的标题和正文。默认情况下通知会在 4500 毫秒后自动关闭;设置duration可控制关闭间隔,设为0则永不自动关闭。注意duration接收的数值单位是毫秒(Number)。

完整示例(继承自官方文档,可直接复制运行):

render() { return ( <div> <Button plain={true} onClick={this.open.bind(this)}>Close automatically</Button> <Button plain={true} onClick={this.open2.bind(this)}>Won't close automatically</Button> </div> ) } open() { Notification({ title: 'Title', message: 'This is a reminder' }); } open2() { Notification({ title: 'Prompt', message: 'This is a message that does not automatically close', duration: 0 }); }

自动关闭的计时器实现

duration的行为在 Notification.jsx 中实现:

startTimer() { const { duration } = this.props if (duration) { this.timeout = setTimeout(() => this.onClose(), duration) } }

两个实现细节值得注意:

  • 默认值来自 Notification.jsx 的defaultProps:duration: 4500, top: 16,与文档 Options 表中duration默认值 4500 完全一致;
  • 由于if (duration)对0为 falsy,duration: 0时根本不会创建定时器,从而实现"不自动关闭",而非"延时 0 毫秒立即关闭"。

onClose(用户传入的关闭回调)与内部状态切换分离:组件先setState({ visible: false })触发退场动画,动画完成后由Transition的onExited钩子再调用外部onClose(见 Notification.jsx 与 L76),因此你的onClose回调在视觉上"完全消失"之后才执行。

三、带类型的通知:success / warning / info / error

Element 提供四种通知类型:success、warning、info与error,通过type字段设置,其他值将被忽略(propTypes中即声明为PropTypes.oneOf(['success', 'warning', 'info', 'error']))。同时库为每种类型注册了快捷方法,可以不传type字段直接调用,例如Notification.info(options)、Notification.error(options)。

render() { return ( <div> <Button plain={true} onClick={this.open3.bind(this)}>Success</Button> <Button plain={true} onClick={this.open4.bind(this)}>Warning</Button> <Button plain={true} onClick={this.open5.bind(this)}>Info</Button> <Button plain={true} onClick={this.open6.bind(this)}>Error</Button> </div> ) } open3() { Notification({ title: 'Success', message: 'This is a success message', type: 'success' }); } open4() { Notification({ title: 'Warning', message: 'This is a warning message', type: 'warning' }); } open5() { Notification.info({ title: 'Info', message: 'This is an info message' }); } open6() { Notification.error({ title: 'Error', message: 'This is an error message' }); }

type 到图标的映射

类型图标在 Notification.jsx 中通过typeMap硬编码:

const typeMap = { success: 'circle-check', info: 'information', warning: 'warning', error: 'circle-cross' };

typeClass()将其转换为el-icon-xxx类名并渲染为<i>元素;这四种图标名均能在官方图标清单 site/pages/icon/iconList.js 中检索到(如circle-check、circle-cross)。当同时设置type与iconClass时,文档说明iconClass会被type覆盖;从源码结构看,渲染时执行classNames('el-notification__icon', this.typeClass(), iconClass),两组类名会同时挂在同一图标元素上,最终的视觉呈现以样式表中后定义的规则为准。

类型快捷方法的注册位置

Notification.info等方法并非单独实现的组件,而是在 NotificationCenter.jsx 末尾通过forEach统一挂在工厂函数上:

['success', 'warning', 'info', 'error'].forEach(type => { NotificationCenter[type] = (options = {}) => NotificationCenter(options, type); });

即快捷方法只是"预设了type参数"的同一入口,所有类型共享同一套堆叠与生命周期逻辑。

字符串简写形式

除 options 字面量外,从源码结构看工厂函数还接受字符串简写:若首个参数是字符串或 React Element,会被包装为{ message: props }(见 NotificationCenter.jsx),且第二个参数可传入类型。TypeScript 声明同样如此定义(typings/index.d.ts):

type NotificationFunction = (options: string | NotificationOptions, type?: typeColor | 'error') => void

类型测试文件 typings/typing-tests/Notification.tsx 中对Notification('message', 'success')、Notification.success('message')等调用形式均有覆盖,可作为合法用法参照。

四、自定义偏移量 offset 与多通知堆叠

设置offset可自定义 Notification 距屏幕顶部的偏移距离。需要注意的是:同一时刻的所有 Notification 实例应当保持相同的 offset,否则会破坏堆叠定位。

render() { return ( <Button plain={true} onClick={this.open.bind(this)}>Notification with offset</Button> ) } open() { Notification({ title: 'Success', message: 'This is a success message', offset: 100 }); }

堆叠与回弹:top 是如何计算的

这条约束来自 NotificationCenter.jsx 的定位算法:

const instances = document.querySelectorAll('.el-notification') const lastInstance = instances[instances.length - 1]; props.top = (lastInstance ? (parseInt(lastInstance.style.top) + lastInstance.offsetHeight) : props.offset) + 16;

即新通知的top取"当前最后一个实例的top加其自身高度",再补 16px 间距;没有任何实例时则回落到offset + 16。这解释了为什么offset必须一致——每个新实例的基准都来自前一个实例的实测位置,而offset只决定整列的起点。

当某个通知关闭时,其上方空间如何被利用?willUnmount回调(NotificationCenter.jsx)会在移 DOM 后通过requestAnimationFrame遍历所有剩余实例,把top大于被关闭实例的元素整体上移"被关闭实例高度 + 16px",实现列表的自动回弹,无需用户干预。

top本身并不是公开选项,它由中心在渲染前注入:Notification视图组件将其直接写入内联样式style={{ top, zIndex: 9999 }}(Notification.jsx),其defaultProps中的top: 16仅在脱离NotificationCenter单独使用时生效。

五、完整选项(Options)参考

继承文档的完整参数表,并对照源码补充了类型约束:

参数说明类型可选值默认值
title标题string——
message说明文字string/ReactElement——
type通知类型,不在可选值内将被忽略stringsuccess/warning/info/error—
iconClass自定义图标类名,若设置了type则被type覆盖string——
duration自动关闭时长(毫秒),设为 0 则不自动关闭number—4500
onClose关闭时的回调函数function——
onClick点击 Notification 时的回调函数function——
offset距屏幕顶部的偏移量,同一时刻所有实例应保持一致number—0

补充说明:

  • message支持 ReactElement 并非仅停留在文档层面:propTypes声明为PropTypes.oneOfType([PropTypes.string, PropTypes.element])(Notification.jsx),message直接作为子节点渲染进el-notification__content,因此可以传入任意图表组件、带富内容的说明区块等;
  • offset未传时由工厂函数显式补默认值 0(NotificationCenter.jsx):if (!props.offset) props.offset = 0;
  • onClick绑在通知根节点上(Notification.jsx),点击通知任意区域都会触发。

六、交互细节:悬停暂停自动关闭

文档选项表未单独列出的一条实用行为来自源码:通知根节点绑定了onMouseEnter={stopTimer}与onMouseLeave={startTimer}(Notification.jsx)。从源码结构看,这意味着鼠标移入通知会清除计时器暂停倒计时,移出后以完整的duration重新计时,而不是从剩余时间继续。对duration: 0的常驻通知无影响。

退场动画由内部Transition(封装自react-transition-group,见 libs/animate/transition.jsx)驱动,使用el-notification-fade-leave-active与el-notification-fade-enter两个淡入淡出类名,并开启unmountOnExit,动画结束后才真正卸载 DOM。

七、Methods 与类型声明的一致性说明

文档Methods一节的描述为:调用Notification会返回当前的通知实例,可对实例调用close手动关闭:

方法说明
close关闭当前的 Notification

对应地,TypeScript 声明(typings/index.d.ts)也给出了完整签名:

interface NotificationOptions { message?: string | React.ReactElement<any> title?: string type?: typeColor | 'error' iconClass?: string duration?: number onClick?(): void onClose?(): void offset?: number } type NotificationFunction = (options: string | NotificationOptions, type?: typeColor | 'error') => void type NotificationObject = { success(options: string | NotificationOptions): void info(options: string | NotificationOptions): void warning(options: string | NotificationOptions): void error(options: string | NotificationOptions): void close(): void } export const Notification: NotificationFunction & NotificationObject

需要如实指出的一处差异:从当前仓库(package.json 版本 1.4.34)的源码实现看,NotificationCenter.jsx 的工厂函数没有 return 语句,运行时也只注册了success/warning/info/error四个类型方法,未注册close;close()仅存在于类型声明与类型测试(typings/typing-tests/Notification.tsx)中。因此在当前版本中,"返回实例并调用close"是文档与类型层面描述的 API 形态,实际关闭请依赖自动计时、duration: 0+ 右上角关闭按钮(el-notification__closeBtn,见 Notification.jsx)或onClose回调。

八、小结:选型与使用要点

  1. 命令式调用:Notification通过ReactDOM.render挂载独立子树,适合在请求拦截器、表单提交回调等任意生命周期外触发全局提示;
  2. 时长控制:duration单位为毫秒、默认 4500,0表示常驻;悬停会暂停倒计时;
  3. 类型化提示:四种type与同名快捷方法一一对应,type决定图标(el-icon-circle-check等),iconClass可用于补充自定义图标;
  4. 布局约束:同一时刻所有实例应共用同一offset,堆叠 top 值与关闭回弹由NotificationCenter自动维护;
  5. 富内容:message可直接传 ReactElement;字符串简写Notification('message', 'success')同样可用;
  6. 类型检查:TS 项目以 typings/index.d.ts 中的NotificationOptions为准,可用typescript-test脚本(npm run typescript-test,见 package.json)验证类型用法。

如需对照原始文档,可查阅 site/docs/en-US/notification.md 与中文版 site/docs/zh-CN/notification.md。

  • 前端
  • UI组件
  • 设计系统

【免费下载链接】element-react

Element UI

项目地址:https://gitcode.com/gh_mirrors/el/element-react
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询