《精通react/vue組件設計》之5分鐘實現一個Tag(標籤)組件和Empty(空狀態)組件

前言

本文是筆者寫組件設計的第五篇文章,之因此會寫組件設計相關的文章,是由於做爲一名前端優秀的前端工程師,面對各類繁瑣而重複的工做,咱們不該該循序漸進的去"辛勤勞動",而是要根據已有前端的開發經驗,總結出一套本身的高效開發的方法.做爲數據驅動的領導者react/vue等MVVM框架的出現,幫咱們減小了工做中大量的冗餘代碼, 一切皆組件的思想深得人心.因此, 爲了讓工程師們有更多的時間去考慮業務和產品迭代,咱們不得不掌握高質量組件設計的思路和方法.因此筆者將花時間去總結各類業務場景下的組件的設計思路和方法,並用原生框架的語法去實現各類經常使用組件的開發,但願等讓前端新手或者有必定工做經驗的朋友能有所收穫.javascript

今天主要帶你們一塊兒實現一個Tag組件和Empty(空狀態)組件,在介紹組件設計以前,先給你們介紹一個免費開源的圖標庫icomoon,css

能夠在線導入SVG格式字體,並進行編輯,而後下載來使用,在組件設計中有具體的使用介紹.

若是對於react/vue組件設計原理不熟悉的,能夠參考個人以前寫的組件設計系列文章:html

正文

在開始組件設計以前但願你們對css3和js有必定的基礎.咱們先看看實現後的組件效果: 前端

由圖能夠知道tag組件能夠自定義顏色主題(color theme), 能夠手動關閉標籤, 空狀態主要是提供用戶數據展現用的, 實現起來很簡單,重點在圖標的使用上.

1. 組件設計思路

按照以前筆者寫的組件設計原則,咱們第一步是要確認需求. 一個tag標籤組件通常都會有以下需求點:vue

  • 能夠改變標籤顏色
  • 提供關閉標籤的配置,讓用戶能夠關閉標籤
  • 關閉標籤的回調,讓用戶能控制標籤關閉後觸發的動做

需求收集好以後,做爲一個有追求的程序員, 會得出以下線框圖:java

對於react選手來講,若是沒用typescript,建議你們都用PropTypes, 它是react內置的類型檢測工具,咱們能夠直接在項目中導入. vue有自帶的屬性檢測方式,這裏就不一一介紹了.

2. 基於react實現一個Tag組件

2.1. tag組件框架設計

首先咱們先根據需求將組件框架寫好,這樣後面寫業務邏輯會更清晰:node

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

首先咱們要想在react的函數式組件操做dom, 最好的方式是使用ref, 關於ref的使用若是不熟悉的能夠參考react官方文檔,這裏實現以下:webpack

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:css3

.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. 可導入,下載,管理本身的圖標庫
  2. 可編輯圖標,生成svg圖標或者字體圖標
    固然國內的iconfont也很是優秀,你們能夠多嘗試.

咱們將下載icomoon圖標文件後,會有一個html的demo文件,裏面有具體的使用方法和離線編輯功能,以下:

筆者在這裏就很少作介紹了, 其次咱們也能夠相似於antd同樣,將icon封裝成react的組件, 這樣用起來也很是方便.

最後

後續筆者將會繼續實現modal(模態窗), alert(警告提示), drawer(抽屜), tooltip(工具提示條), Skeleton(骨架屏), Message(全局提示), 日期/日曆等組件, 來複盤筆者多年的組件化之旅. 若是想學習更多H5遊戲, webpacknodegulpcss3javascriptnodeJScanvas數據可視化等前端知識和實戰,歡迎在公號《趣談前端》加入咱們一塊兒學習討論,共同探索前端的邊界。

更多推薦

相關文章
相關標籤/搜索