文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

精通React/Vue系列之手把手带你实现一个功能强大的通知提醒框(Notification)

2024-12-02 05:17

关注
<Modal title="xui基础弹窗" centered mask={false} visible={false}>
<p>我是弹窗内容p>
<p>我是弹窗内容p>
<p>我是弹窗内容p>
<p>我是弹窗内容p>
Modal>

但是通知提醒框(Notification),大多数场景下是使用js API的方式调用:

notification.open({
message: '趣谈前端React',
description: '学前端,学React/vue/Node,快快加入我们吧'
});

我们看到的组件效果可能是这样的:

那么我们如何实现这样的调用方式呢?不用急,接下来笔者会一步步教你实现。

先来巩固以下组件的分类法:

熟悉以上分类法是设计任何组件系统的前提,不管你是从零到一开发前端团队的UI库,还是基于已有组件库二次开发业务组件,以上分类法则同样适用。本文将会使用React来开发该组件,也会使用到Javascript中常用的一些设计模式,比如单例模式,但是不管你使用什么框架来实现,原理都是通用的,如果感兴趣的朋友可以用vue也实现以一下。

正文

在开始组件设计之前希望大家对css3和js有一定的基础,并了解基本的react/vue语法.我们先来解构一下Notification组件, 一个Notification分为以下几个部分:

每一个区块都可以自定义配置, 也可以组合其他组件.并且我们可以配置提醒框出现的位置,就像antd的组件一样,我们有左上,左下,右上,右下这几个位置可以配置,也可以配置基于这几个位置的偏移量。并且我们都知道,antd或者element这种组件库,会自带一些主题状态,来提高用户的使用效率,比如会有success(成功状态),warning(警告状态),error(错误状态),info(通知状态)等,那么我们自己实现的组件也因该具备这些功能。

以下是笔者使用React实现后的Notification组件效果:

接下来我们来看看通知提醒框(Notification)的具体设计思路。

1. Notification组件设计思路

按照之前笔者总结的组件设计原则,我们第一步是要确认需求. 通知提醒框(Notification)组件一般会有如下需求点:

需求收集好之后,作为一个有追求的程序员, 会得出如下线框图:

其实通知提醒框要考虑的东西挺多的,所以在设计组件之前,一定要想理清需求和功能划分,这样才能有条不絮的去实现它,和我们实现一个复杂系统是一样的,一个组件就是一个小系统。

2. 基于react实现一个通知提醒框(Notification)

通知框的API调用实现思路其实就是通过jsx动态渲染约定好的标签,然后通过ReactDom的Render API将dom渲染到指定容器内挂载到页面,其中要想实现Notification.info这样的方式还需要考虑到创建实例的问题,我们应该使用单例模式来控制实例的创建个数。伪代码如下:

const xNotification = (function() {
let notification = null;
if(notification) {
return {
render(dom){},
config(config){},
info(config){},
error(config){}
// ...
}
}else {
notification = new Notification({})
return {
render(dom){},
config(config){},
info(config){},
error(config){}
// ...
}
}
})()
// 使用
xNotification.info({...})
xNotification.error({...})

但是真正要实现以上需求讨论的那些通知框的功能,实际上我们还是要写很多代码来处理不同的情况的,所以为了方便大家理解,我们这里使用React Notification这个第三方库来帮我们处理基本的逻辑,笔者会基于它,来实现上面我们讨论的那些功能。

2.1 搭建通知提醒框(Notification)的基本骨架

首先按照笔者的代码风格,一般会考虑组件设计的框架,然后再一步步往里面填充内容和逻辑。通过这种渐进式的设计思路,能让我们逻辑更严谨,更清晰。具体代码如下:

import Notification from 'rc-notification'
import './index.less'

const xNotification = (function() {
let notification = null

const pop = (config) => {
const {
type, bottom, className, description, duration = 4.5,
getContainer = () => document.body, icon,
key, message, onClose, onClick, top, closable = true, closeIcon
} = config
notification.notice({
content: <div className={classnames('xNotice', className )}>
<div className={classnames('iconWrap', type)}>
<Icon type={iconType[type]} />
div>
<div>
<div className="xNoticeTit">
{ message }
div>
<div className="xNoticeDesc">
{ description }
div>
div>
div>
})
}

const config = (config) => {
const { duration, getContainer, placement, closeIcon } = config
Notification.newInstance({
getContainer: getContainer,
duration: duration || 4.5,
closeIcon
}, (notice) => notification = notice)
}

if(notification) {
return {
config,
pop
}
}
// 如果为创建实例,则创建默认实例
Notification.newInstance({}, (notice) => notification = notice)
return {
config,
pop
}
})()

export default xNotification

首先我们根据需求把一项项的属性都罗列出来。我们在全局使用的配置方法是xNotification.config(config), 在通知框实例中我们使用xNotification.pop(config)。这点和antd的使用方式有点不同,笔者是把通知框类型放到pop的config来处理了,比如说要渲染一个成功的通知框,我们可以这么做:

xNotification.pop({type: 'success'})

antd同样的方式会这么调用:

// antd
Notification.info({//...})

笔者之所以会这么做是因为info,success,warning这样的状态其实dom结构完全可以复用,所以通过配置方式可以极大的减少冗余代码。

2.2 实现通知框类型type和自定义icon

笔者其实在搭建组件框架的时候已经完成了部分属性的配置,所以这里就不一一介绍了,笔者将会介绍一些比较重要的方法的实现。

通过观察我们可以知道要想实现不同的通知框类型,只需要根据类型来动态替换icon就行了。icon图标部分采用笔者已经实现的Icon组件,具体用法和antd的Icon组件类似,如果想学习如何封装属于自己的Icon组件可以参考笔者源码。

首先我们先定义一个类型和icon的映射关系:

const iconType = {
success: 'FaRegCheckCircle',
warning: 'FaRegMeh',
info: 'FaRegLightbulb',
error: 'FaRegTimesCircle'
}

这四种类型对应着不同的icon图标类型,那么我们就可以根据用户传入的类型来展示不同icon图标了:

<div className={classnames('iconWrap', type)}>
<Icon type={iconType[type]} />
div>

不过我们还需要考虑的一点就是如果用户传入了自定义的icon,我们理论上应该展示自定义icon,所以type因该和icon这两个属性是有联系的。还有一种情况就是如果用户即没有配置type,有没有传入icon,那么实际上是不需要显示icon的,综合考虑之后我们的代码如下:

{
(icon || ['info', 'success', 'error', 'warning'].indexOf(type) > -1) &&
<div className={classnames('iconWrap', type)}>
{
icon ? icon : <Icon type={iconType[type]} />
}
div>

实现效果如下图:

2.3 通知框位置placement

通知框的位置根据业务场景来看因该是全局配置,所以我们放在config方法里设置,关于如何根据用户传入的位置信息来控制Notification显示的位置,我们也可以先定义一个枚举类:

const adapterPos = {
topLeft: {
top: '24px',
left: '24px'
},
topRight: {
top: '24px',
right: '24px'
},
bottomLeft: {
bottom: '24px',
left: '24px'
},
bottomRight: {
bottom: '24px',
right: '24px'
}
}

从上面代码可以看到我们会定义四个基础位置,默认偏移都是24px,然后我们就可以根据用处传入的placement来匹配自己的位置信息了:

Notification.newInstance({
style: {...adapterPos[placement] },
// ...

上面代码可以知道位置信息我们是通过style来设置的。具体效果如下:

2.4 实现通知框动画效果

动画我们实现一个类似于antd的从右往左入场的动画,我们来改写样式如下:

.rc-notification-fade-enter {
animation: moveLeft .3s;
}
.rc-notification-fade-leave {
animation: moveOutLeft .3s;
}
.rc-notification-fade-enter.rc-notification-fade-enter-active {
animation: moveLeft .3s;
}
.rc-notification-fade-leave.rc-notification-fade-leave-active {
animation-name: moveOutLeft .3s;
}

@keyframes moveOutLeft {
0% {

}
100% {
right: -200%;
}
}
@keyframes moveLeft {
0% {
right: -200%;
}
100% {
right: 0;
}
}

通过以上步骤, 一个功能强大的通知提醒框(Notification)就完成了.Notification组件算是组件库中中等复杂的组件,如果不懂的可以在评论区提问,笔者看到后会第一时间解答。

2.5 使用Notification组件

我们可以通过如下方式使用它:

<Button type="primary" onClick={
() => {
xNotification.pop({
type: 'success',
message: '趣谈前端学习打卡',
description: '前端基础,中级进阶,高级打卡,一起玩转前端,996远离你'
})
}
}>点我显示通知Button>

配置全局属性:

import { xNotification } from '@alex_xu/xui'

xNotification.config({
placement: 'topRight'
})

笔者已经将实现过的组件发布到npm上了,大家如果感兴趣可以直接用npm安装后使用,方式如下;

pm i @alex_xu/xui

// 导入xui
import {
Button,
Skeleton,
Empty,
Progress,
Tag,
Switch,
Drawer,
Badge,
Alert
} from '@alex_xu/xui'

该组件库支持按需导入,我们只需要在项目里配置babel-plugin-import即可,具体配置如下:

/ .babelrc
"plugins": [
["import", { "libraryName": "@alex_xu/xui", "style": true }]
]

npm库截图如下:

来源:趣谈前端内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯