- 前端
- UI组件
- 设计系统
【免费下载链接】element-react
Element UI
本篇基于 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 可以看到完整的命令式流程:
document.createElement('div')创建一个临时挂载点并appendChild到document.body;- 若传入的参数是字符串或合法的 React Element,则自动包装为
{ message: props }; - 若第二个参数
type存在,则写入props.type; - 计算
props.top(见下文堆叠机制),随后React.createElement(Notification, ...)并ReactDOM.render(element, div)独立渲染; - 通知关闭动画结束后,
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 | 通知类型,不在可选值内将被忽略 | string | success/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回调。
八、小结:选型与使用要点
- 命令式调用:
Notification通过ReactDOM.render挂载独立子树,适合在请求拦截器、表单提交回调等任意生命周期外触发全局提示; - 时长控制:
duration单位为毫秒、默认 4500,0表示常驻;悬停会暂停倒计时; - 类型化提示:四种
type与同名快捷方法一一对应,type决定图标(el-icon-circle-check等),iconClass可用于补充自定义图标; - 布局约束:同一时刻所有实例应共用同一
offset,堆叠 top 值与关闭回弹由NotificationCenter自动维护; - 富内容:
message可直接传 ReactElement;字符串简写Notification('message', 'success')同样可用; - 类型检查: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
相关推荐
MAS 3 步激活 Windows 与 Office:个人用户实操指南
MAS 3 步激活 Windows 与 Office:个人用户实操指南 Windows 11 和 Office 没有密钥、没有企业 KMS,急需激活?MAS(M
操作系统Element Plus Notification 通知组件完全指南:全局调用、类型体系与源码级原理剖析
Element Plus Notification 通知组件完全指南:全局调用、类型体系与源码级原理剖析 Notification 是 Element Plus
前端UI组件如何用 Dify DSL 工作流 10 分钟搭出一个能登录的应用
如何用 Dify DSL 工作流 10 分钟搭出一个能登录的应用 演示前夜,产品经理甩来一句话:明天要给客户看一个能登录的交互原型。你本来以为得拉前端排期两天,
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考