您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

《精通react/vue组件设计》之实现一个健壮的警告提示(Alert)组件

时间:2023-09-05 11:51:48  来源:微信公众号  作者: 趣谈前端
图片

 

前言

本文是笔者写组件设计的第七篇文章, 今天带大家实现一个自带主题且可关闭的Alert组件, 该组件在诸如Antd或者elementUI等第三方组件库中都会出现,主要用来提供系统的用户反馈.

之所以会写组件设计相关的文章,是因为作为一名前端优秀的前端工程师,面对各种繁琐而重复的工作,我们不应该按部就班的去"辛勤劳动",而是要根据已有前端的开发经验,总结出一套自己的高效开发的方法.

前端组件一般会划分为如下几种类型:

  • 通用型组件: 比如Button, Icon等.
  • 布局型组件: 比如Grid, Layout布局等.
  • 导航型组件: 比如面包屑Breadcrumb, 下拉菜单Dropdown, 菜单Menu等.
  • 数据录入型组件: 比如form表单, Switch开关, Upload文件上传等.
  • 数据展示型组件: 比如Avator头像, Table表格, List列表等.
  • 反馈型组件: 比如Progress进度条, Drawer抽屉, Modal对话框等.
  • 其他业务类型
所以我们在设计组件系统的时候可以参考如上分类去设计,该分类也是antd, element, zend等主流UI库的分类方式.

正文

在开始组件设计之前希望大家对css3和js有一定的基础,并了解基本的react/vue语法.我们先看看实现后的组件效果:

图片

1. 组件设计思路

按照之前笔者总结的组件设计原则,我们第一步是要确认需求. 一个警告提示(Alert)组件会有如下需求点:

  • 能控制Alert组件的样式
  • 能控制Alert组件的关闭按钮是否显示
  • 用户可以自己输入提示内容
  • 能控制关闭按钮的文本,或者自定义关闭按钮
  • 支持显示提示内容的辅助文本
  • 内置提供不同类型的警告提示样式,比如成功, 错误, 警告等
  • 关闭提示时能提供自定义事件
需求收集好之后,作为一个有追求的程序员, 会得出如下线框图:
图片

对于react选手来说,如果没用typescript,建议大家都用PropTypes, 它是react内置的类型检测工具,我们可以直接在项目中导入. vue有自带的属性检测方式,这里就不一一介绍了.

通过以上需求分析, 我们发现实现一个Alert非常简单, 它属于反馈型组件,所以不会涉及到太多功能.接下来我们就来看看具体实现.

2. 基于react实现一个Alert组件

2.1. Alert组件框架设计

首先我们先根据需求将组件框架写好,这样后面写业务逻辑会更清晰:

import classnames from 'classnames'import styles from './index.less'
/** * 警告提示组件 * @param {style} object 更改Alert样式 * @param {closable} bool 是否显示关闭按钮, 默认不显示 * @param {closeText} string|reactNode 自定义关闭按钮 * @param {message} string 警告提示内容 * @param {description} string 警告提示的辅助性文字 * @param {type} string 警告的类型 * @param {onClose} func 关闭时触发的事件 */function Alert(props) {  const {    style,    closable,    closeText,    message,    description,    type,    onClose  } = props
  return <div className={styles.xAlertWrap}>          <div className={styles.alertMes}>{ message }</div>          <div className={styles.alertDesc}>{ description }</div>          <span className={styles.closeBtn}>{ closeText ? closeText : 'x' }</span>         </div>}
export default Alert

有了这个框架,我们就来往里面实现内容吧.

2.2 实现style,closeText,message, description,type

这几个功能在框架搭建好之后已经部分实现了,是因为他们都比较简单,不会牵扯到其他复杂逻辑.只需要对外暴露属性并使用属性即可. 具体实现如下:

function Alert(props) {  const {    style,    closable,    closeText,    message,    description,    type,    onClose  } = props
  return <div       className={classnames(styles.xAlertWrap, styles[type] || styles.warning)}      style={{        ...style      }}    >      <div className={styles.alertMes}>{ message }</div>      <div className={styles.alertDesc}>{ description }</div>      <span className={styles.closeBtn}>{ closeText ? closeText : 'x' }</span>    </div>}

以上代码可以发现笔者采用了classnames这个第三方工具, 他可以组合我们的class以实现更灵活的配置. 对于type的实现,我的思路是提前预制好几种类型样式, 通过用户手动配置来匹配到对应的样式:

.xAlertWrap {  box-sizing: border-box;  position: relative;  padding: 5px 12px;  margin-bottom: 16px;  border-radius: 3px;  &.success {    background-color: #f6ffed;    border: 1px solid #b7eb8f;  }  &.info {    background-color: #e6f7ff;    border: 1px solid #91d5ff;  }  &.error {    background-color: #fffbe6;    border: 1px solid #ffe58f;  }  &.warning {    background-color: #fff1f0;    border: 1px solid #ffa39e;  }}

2.3 实现closable和onClose

closable主要是用来让用户能手动关闭Alert,onClose是对外暴露的关闭时的方法, 因为没必要也不需要向外暴露属性来让Alert关闭, 所以最好的方式是在组件内部实现, 我们会通过useState这个钩子来处理,代码如下:

function Alert(props) {  const {    style,    closable,    closeText,    message,    description,    type,    onClose  } = props  let [visible, setVisible] = useState(true)
  const handleColse = () => {    setVisible(false)    onClose && onClose()  }  return visible ?     <div       className={classnames(styles.xAlertWrap, styles[type] || styles.warning)}      style={{        opacity: visible ? '1' : '0',        ...style      }}    >      <div className={styles.alertMes}>{ message }</div>      <div className={styles.alertDesc}>{ description }</div>      {        !!closable && <span className={styles.closeBtn} onClick={handleColse}>{ closeText ? closeText : 'x' }</span>      }    </div> : null}

通过控制visible来控制Alert的出现和消失, 并且当点击关闭按钮时能调用外部暴露的onClose方法.

2.4 健壮性支持, 我们采用react提供的propTypes工具:

import PropTypes from 'prop-types'// ...Alert.propTypes = {  style: PropTypes.object,  closable: PropTypes.bool,  closeText: PropTypes.oneOfType([    PropTypes.string,    PropTypes.element  ]),  message: PropTypes.string,  description: PropTypes.string,  type: PropTypes.string,  onClose: PropTypes.func}

关于prop-types的使用官网上有很详细的案例,这里说一点就是oneOfType的用法, 它用来支持一个组件可能是多种类型中的一个.  组件完整css代码如下:

.xAlertWrap {  box-sizing: border-box;  position: relative;  padding: 5px 12px;  margin-bottom: 16px;  border-radius: 3px;  &.success {    background-color: #f6ffed;    border: 1px solid #b7eb8f;  }  &.info {    background-color: #e6f7ff;    border: 1px solid #91d5ff;  }  &.error {    background-color: #fffbe6;    border: 1px solid #ffe58f;  }  &.warning {    background-color: #fff1f0;    border: 1px solid #ffa39e;  }
  .alertMes {    margin-bottom:5px;    color: rgba(0, 0, 0, 0.85);    font-size: 14px;    line-height: 1.5em;  }  .alertDesc {    color: rgba(0, 0, 0, 0.65);    font-size: 14px;    line-height: 1.5em;    word-break: break-all;  }  .closeBtn {    position: absolute;    right: 8px;    top: 5px;    color: rgba(0, 0, 0, 0.4);    cursor: pointer;  }}

通过以上步骤, 一个健壮的的Alert组件就完成了,关于代码中的css module和classnames的使用大家可以自己去官网学习,非常简单.如果不懂的可以在趣谈前端技术群里提问,笔者看到后会第一时间解答.

2.5 使用Alert组件

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

<Alert message="温馨提示,你忘带口罩了" /><Alert message="温馨提示,你注册成功" type="success" /><Alert message="错误提示,你没洗手了" type="error" /><Alert message="提示: 我们开始吧" type="info" /><Alert message="提示: 我可以关闭了" type="info" closable onClose={() => { alert(111) }} /><Alert message="注册成功" description="你在本网站已经注册成功,谢谢您的支持和反馈,多交流真正的技术吧" closable type="success" />

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

npm i @alex_xu/xui// 导入xuiimport {  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库截图如下:

图片

 

 

最后

之前笔者已经实现了:

  • modal(模态窗),
  • badge(徽标),
  • table(表格),
  • tooltip(工具提示条),
  • Skeleton(骨架屏),
  • Message(全局提示),
  • form(form表单),
  • switch(开关),
  • 日期/日历,
  • 二维码识别器组件

等组件, 来复盘笔者多年的组件化之旅.

如果想获取组件设计系列完整源码, 或者想学习更多H5游戏webpacknodegulpcss3javascriptnodeJScanvas数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入我们的技术群一起学习讨论,共同探索前端的边界。



Tags:组件   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  Search: 组件  点击:(8)  评论:(0)  加入收藏
浅析五种 React 组件设计模式
作为一名 React 开发者,你可能会面临下面几个问题: 如何构建一个高复用度性的组件,使其适应不同的业务场景? 如何构建一个具有简单 API的组件,使其易于使用? 如何构建一个在 UI 和...【详细内容】
2024-01-09  Search: 组件  点击:(81)  评论:(0)  加入收藏
浅谈ArkUI之Web组件的基础用法
最近研究了ArkUI中的一些常用组件,其中Web组件是很常用且相对独立的一种组件。本文总结了Web组件的常用函数,以及基本用法。先来一个AI画的Web组件助助兴(好吧,不能说毫无关系,只...【详细内容】
2023-12-29  Search: 组件  点击:(94)  评论:(0)  加入收藏
如何设计更优雅的 React 组件?
在日常开发中,团队中每个人组织代码的方式不尽相同。下面我们就从代码结构的角度来看看如何组织一个更加优雅的 React 组件!1. 导入依赖项我们通常会在组件文件顶部导入组件所...【详细内容】
2023-12-21  Search: 组件  点击:(101)  评论:(0)  加入收藏
七个常用的 Vue 3 UI 组件
介绍:由于我在工作的公司中角色和职责的变化,作为后端开发人员的我在去年年底选择了 Vue.js。当我深入研究时,我发现 Vue.js 非常有趣。它不像 Angular 那样有很高的学习曲线,而...【详细内容】
2023-12-20  Search: 组件  点击:(78)  评论:(0)  加入收藏
五分钟搞懂Kubernetes:轻松理解所有组件
之前我曾经提到了一系列关于服务网格的内容。然而,我意识到有些同学可能对Kubernetes的了解相对较少,更不用说应用服务网格这个概念了。因此,今天我决定带着大家快速理解Kubern...【详细内容】
2023-12-06  Search: 组件  点击:(150)  评论:(0)  加入收藏
如何使用Web组件制作可定制的天气小部件
译者 | 李睿审校 | 重楼天气小部件在许多网站和应用程序中都很常见,用户可以快速浏览特定位置的天气状况。但是,如果人们可以创建自己的可定制天气小部件,使其与自己网站的主题...【详细内容】
2023-12-06  Search: 组件  点击:(157)  评论:(0)  加入收藏
计算机硬件组件解析:探秘硬件之间的作用与关系
计算机作为现代科技的核心,其性能和功能的实现离不开各种关键的硬件组件。本文将深入介绍计算机的核心硬件,包括中央处理器(CPU)、图形处理器(GPU)、内存和存储设备等,旨在解释它们...【详细内容】
2023-11-24  Search: 组件  点击:(276)  评论:(0)  加入收藏
微软AR/VR专利提出改善显示组件失准校正的方法
MR系统通常包括单独的显示组件,并分别配置在用户的眼睛前面。然而,立体错位经常发生在MR系统中,亦即通过单独显示组件显示的内容没有正确对齐。立体错位可能导致用户在混合现实...【详细内容】
2023-11-24  Search: 组件  点击:(155)  评论:(0)  加入收藏
如何用低代码的思路设计文字描边渐变组件
前言文字特效设计一直是困扰 Web 前端 Css 世界多年的问题, 比如如何用纯 Css 实现文字描边, 渐变, 阴影等, 由于受限于浏览器兼容性的问题, 我们不得不使用其他替代方案来...【详细内容】
2023-11-23  Search: 组件  点击:(160)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
站内最新
站内热门
站内头条