《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件

徐小夕 等级 319 0 0

前言

本文是笔者写组件设计的第五篇文章,之所以会写组件设计相关的文章,是因为作为一名前端优秀的前端工程师,面对各种繁琐而重复的工作,我们不应该按部就班的去"辛勤劳动",而是要根据已有前端的开发经验,总结出一套自己的高效开发的方法.作为数据驱动的领导者react/vue等MVVM框架的出现,帮我们减少了工作中大量的冗余代码, 一切皆组件的思想深得人心.所以, 为了让工程师们有更多的时间去考虑业务和产品迭代,我们不得不掌握高质量组件设计的思路和方法.所以笔者将花时间去总结各种业务场景下的组件的设计思路和方法,并用原生框架的语法去实现各种常用组件的开发,希望等让前端新手或者有一定工作经验的朋友能有所收获.

今天主要带大家一起实现一个Tag组件和Empty(空状态)组件,在介绍组件设计之前,先给大家介绍一个免费开源的图标库icomoon,

《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件 可以在线导入SVG格式字体,并进行编辑,然后下载来使用,在组件设计中有具体的使用介绍.

如果对于react/vue组件设计原理不熟悉的,可以参考我的之前写的组件设计系列文章:

正文

在开始组件设计之前希望大家对css3和js有一定的基础.我们先看看实现后的组件效果: 《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件 由图可以知道tag组件可以自定义颜色主题(color theme), 可以手动关闭标签, 空状态主要是提供用户数据展示用的, 实现起来很简单,重点在图标的使用上.

1. 组件设计思路

按照之前笔者写的组件设计原则,我们第一步是要确认需求. 一个tag标签组件一般都会有如下需求点:

  • 可以改变标签颜色
  • 提供关闭标签的配置,让用户可以关闭标签
  • 关闭标签的回调,让用户能控制标签关闭后触发的动作

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

《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件 对于react选手来说,如果没用typescript,建议大家都用PropTypes, 它是react内置的类型检测工具,我们可以直接在项目中导入. vue有自带的属性检测方式,这里就不一一介绍了.

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

2.1. tag组件框架设计

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

import React from 'react'
import classnames from 'classnames'
import styles from './index.less'

/**
 * 标签组件
 * @param {closable} boolean 是否可关闭
 * @param {onClose} func 标签关闭时的回调
 * @param {color} string 标签的颜色,不设置则为默认颜色
 */
export default function Tag(props) {
  let { children, closable, onClose, color } = props
  return <div 
    className={styles.xTag} 
    style={{ backgroundColor: color }}
    { children } 
  </div>
}

有了这个框架,我们来一步步往里面实现内容吧. 根据需求,颜色这个属性好实现,在上述代码中已经实现了, 我们看看closable和onClose如何实现.我们要向关闭tag,实际上是需要将这个标签隐藏,比如说使用display:none,或者从dom中移除, 笔者就参考antd的实现方式,通过display:none来实现.

首先我们要想在react的函数式组件操作dom, 最好的方式是使用ref, 关于ref的使用如果不熟悉的可以参考react官方文档,这里实现如下:

import React from 'react'
import classnames from 'classnames'
import styles from './index.less'

/**
 * 标签组件
 * @param {closable} boolean 是否可关闭
 * @param {onClose} func 标签关闭时的回调
 * @param {color} string 标签的颜色,不设置则为默认颜色
 */
export default function Tag(props) {
  let { children, closable, onClose, color } = props
  let tag = React.createRef()
  let handleClose = () => {
    onClose && onClose()
    tag.current.style.display = 'none'
  }
  return <div 
    className={classnames(styles.xTag, color ? styles.xTagHasColor : '')} 
    style={{ backgroundColor: color }}
    ref={tag}>
    { children } 
    { closable && <span className={styles.closeBtn} onClick={handleClose}>x</span> }
  </div>
}

通过react的createRef API,我们很方便的拿到了当前的dom对象, 在handleClose可以进行属性的分配. 组件的js代码基本实现完成了,接下来看看css:

.xTag {
  margin-bottom: 8px;
  margin-right: 8px;
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 0 7px;
  font-size: 12px;
  line-height: 20px;
  white-space: nowrap;
  background-color: #fafafa;
  &.xTagHasColor {
    border-color: transparent;
    color: #fff;
    .closeBtn {
      color: rgba(255, 255, 255, .6)
    }
  }
  .closeBtn {
    margin-left: 5px;
    color: rgba(0, 0, 0, 0.45);
    cursor: pointer;
  }
}

健壮性支持:

import PropTypes from 'prop-types'
// ...
Tag.propTypes = {
  color: PropTypes.string,
  closable: PropTypes.bool,
  onClose: PropTypes.func
}

是不是很简单? 这样一个可定制对的tag组件就完成了,关于代码中的css module和classnames的使用大家可以自己去官网学习,非常简单.

3. 基于react实现一个Empty(空状态)组件

这个组件非常好写, 目前常用的空状态组件一般是图片和文字组合, 图片文字都可替换,具体实现如下:

import classnames from 'classnames'
import styles from './index.less'

/**
 * 空状态组件
 * @param {className} string 自定义类名
 * @param {text} string 空状态文本
 */
export default function Empty(props) {
  let { text, className } = props

  return <div className={classnames(styles.emptyWrap, className)}>
    <div className={styles.emptyInner}><span className="icon-finder"></span></div>
    <p>{ text ? text : '空空如也'}</p>
  </div>
}

这里主要介绍icon-finder的由来.正如文章开始提到的,笔者采用icomoon作为图标库, 我们可以在其官网上定制自己的图标,笔者大概选了40多了免费图标,项目中使用基本够用了.主要介绍一下他的具体功能:

  1. 可导入,下载,管理自己的图标库 《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件
  2. 可编辑图标,生成svg图标或者字体图标 《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件 当然国内的iconfont也非常优秀,大家可以多尝试.

我们将下载icomoon图标文件后,会有一个html的demo文件,里面有具体的使用方法和离线编辑功能,如下:

《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件 笔者在这里就不多做介绍了, 其次我们也可以类似于antd一样,将icon封装成react的组件, 这样用起来也非常方便.

最后

后续笔者将会继续实现modal(模态窗), alert(警告提示), drawer(抽屉), tooltip(工具提示条), Skeleton(骨架屏), Message(全局提示), 日期/日历等组件, 来复盘笔者多年的组件化之旅. 如果想学习更多H5游戏, webpacknodegulpcss3javascriptnodeJScanvas数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。

《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件

更多推荐

收藏
评论区

相关推荐

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)
前言 本文将带大家一步步实现一个H5拼图小游戏,考虑到H5游戏的轻量级和代码体积,我没有使用react或vue这些框架,而采用我自己写的dom库和原生javascript来实现业务功能,具体库代码可见我的文章如何用不到200行代码写一款属于自己的js类库(https://juejin.im/post/6844903880707293198),构建工具我采
vue-toy: 200行代码模拟Vue实现
vuetoy 200行左右代码模拟vue实现,视图渲染部分使用React来代替Sanbbdom,欢迎Star。 项目地址:https://github.com/bplok20010/vuetoy(https://github.com/bplok20010/vuetoy) codesandbox示例(https://codes
前端组件/库打包利器rollup使用与配置实战
目前主流的前端框架vue和react都采用rollup来打包,为了探索rollup的奥妙,接下来就让我们一步步来探索,并基于rollup搭建一个库打包脚手架,来发布自己的库和组件。 (https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/16cb1c297071015523fb08d9e0f
基于jsoneditor二次封装一个可实时预览的json编辑器组件(react版)
前言 做为一名前端开发人员,掌握vue/react/angular等框架已经是必不可少的技能了,我们都知道,vue或react等MVVM框架提倡组件化开发,这样一方面可以提高组件复用性和可扩展性,另一方面也带来了项目开发的灵活性和可维护,方便多人开发协作.接下来文章将介绍如何使用react,开发一个自定义json编辑器组件.我们这里使用了jsoneditor
《精通react/vue组件设计》之用纯css打造类materialUI的按钮点击动画并封装成react组件
前言 作为一个前端框架的重度使用者,在技术选型上也会非常注意其生态和完整性.笔者先后开发过基于vue,react,angular等框架的项目,碧如vue生态的elementUI, antdesignvue, iView等成熟的UI框架, react生态的antdesign, materialUI等,这些第三方UI框架极大的降低了我们开发一个项目的成本和
《精通react/vue组件设计》之快速实现一个可定制的进度条组件
前言 这篇文章是笔者写组件设计的第四篇文章,之所以会写组件设计相关的文章,是因为作为一名前端优秀的前端工程师,面对各种繁琐而重复的工作,我们不应该按部就班的去"辛勤劳动",而是要根据已有前端的开发经验,总结出一套自己的高效开发的方法.作为数据驱动的领导者react/vue等MVVM框架的出现,帮我们减少了工作中大量的冗余代码, 一切皆组件的思想深得人心.所以
《精通react/vue组件设计》之5分钟实现一个Tag(标签)组件和Empty(空状态)组件
前言 本文是笔者写组件设计的第五篇文章,之所以会写组件设计相关的文章,是因为作为一名前端优秀的前端工程师,面对各种繁琐而重复的工作,我们不应该按部就班的去"辛勤劳动",而是要根据已有前端的开发经验,总结出一套自己的高效开发的方法.作为数据驱动的领导者react/vue等MVVM框架的出现,帮我们减少了工作中大量的冗余代码, 一切皆组件的思想深得人心.所以,
《精通react/vue组件设计》之配合React Portals实现一个功能强大的抽屉(Drawer)组件
前言 本文是笔者写组件设计的第六篇文章,内容依次从易到难,今天会用到react的高级API React Portals,它也是很多复杂组件必用的方法之一. 通过组件的设计过程,大家会接触到一个完成健壮的组件设计思路和方法,也能在实现组件的过程逐渐对react/vue的高级知识和技巧有更深的理解和掌握,并且在企业实际工作做游刃有余. 之所以会写组件设计相关
Taro 入门教程
简介 Taro 是一个遵循 React 语法规范的开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/
MobX 上手指南
之前用 Redux 比较多,一直听说 Mobx 能让你体验到在 React 里面写 Vue 的感觉,今天打算尝试下 Mobx 是不是真的有写 Vue 的感觉。 题外话 在介绍 MobX 的用法之前,先说点题外话,我们可以看一下 MobX 的中文简介。在 MobX 的中文网站上写着: MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程
【Flutter实战】状态管理
3.2 状态管理响应式的编程框架中都会有一个永恒的主题——“状态(State)管理”,无论是在React/Vue(两者都是支持响应式编程的Web开发框架)还是Flutter中,他们讨论的问题和解决的思想都是一致的。所以,如果你对React/Vue的状态管理有了解,可以跳过本节。言归正传,我们想一个问题,StatefulWidget的状态应该被谁管理?
新手学习 React 迷惑的点
网上各种言论说 React 上手比 Vue 难,可能难就难不能深刻理解 JSX,或者对 ES6 的一些特性理解得不够深刻,导致觉得有些点难以理解,然后说 React 比较难上手,还反人类啥的,所以我打算写两篇文章来讲新手学习 React 的时候容易迷惑的点写出来,如果你还以其他的对于学习 React 很迷惑的点,可以在留言区里给我留言。为什么要引入 Reac
2021前端技术面试必备Vue:(四)Vuex状态管理
前三章陆续已经更新了Vue基本使用 和Vue Router的基本使用,如果你读了前三篇文章的话,并且掌握差不多,那么你现在可以开发简单的应用了,例如Blog,电商网站........唯一不足的是,随着你的业务需求不断增加,页面中的状态数据也不断庞大,维护起来就特别困难了,Vue 提供了一种状态管理 解决办法 Vuex,它的思想和React 的R
面向初学者的 React 路由-React Router的完整指南!
因此,您正在尝试学习React.js。也许您甚至已经在其中构建了几个简单的项目。无论您是新开发人员还是有一定经验的人,都可能会发现自己必须开发具有不同页面和路线的Web应用程序。那就是React Router发挥作用的时候。什么是React Router?React Router提供了一种在React或React Native应用程序中实现路由的简便方法。入
如何在React Native和Expo中掩盖Text和TextInput组件
在本文中,我将向您展示如何在React Native和Expo中使用自定义蒙版,可用于iOS,Android和Web!我们将使用一个名为库,这是一个没有本机代码的完整javascript库,然后您可以在React Native环境的所有CLI中使用。](https://res.cloudinary.com/practicaldev/image/fetch/s