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

2020-12-22 酷扯兒

本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫

前言

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

今天主要帶大家一起實現一個Tag組件和Empty(空狀態)組件,在介紹組件設計之前,先給大家介紹一個免費開源的圖標庫icomoon,

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

正文

在開始組件設計之前希望大家對css3和js有一定的基礎.我們先看看實現後的組件效果:

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

1. 組件設計思路

按照之前筆者寫的組件設計原則,我們第一步是要確認需求. 一個tag標籤組件一般都會有如下需求點:

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

需求收集好之後,作為一個有追求的程式設計師, 會得出如下線框圖:

對於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多了免費圖標,項目中使用基本夠用了.主要介紹一下他的具體功能:

可導入,下載,管理自己的圖標庫

可編輯圖標,生成svg圖標或者字體圖標

當然國內的iconfont也非常優秀,大家可以多嘗試.

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

筆者在這裡就不多做介紹了, 其次我們也可以類似於antd一樣,將icon封裝成react的組件, 這樣用起來也非常方便.

相關焦點

  • 《精通react/vue組件設計》之快速實現一個可定製的進度條組件
    而是要根據已有前端的開發經驗,總結出一套自己的高效開發的方法.作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗餘代碼, 一切皆組件的思想深得人心.所以, 為了讓工程師們有更多的時間去考慮業務和產品迭代,我們不得不掌握高質量組件設計的思路和方法.所以筆者將花時間去總結各種業務場景下的組件的設計思路和方法,並用原生框架的語法去實現各種常用組件的開發,希望等讓前端新手或者有一定工作經驗的朋友能有所收穫
  • 精通react/vue組件設計之配合React Portals實現一個(Drawer)組件
    通過組件的設計過程,大家會接觸到一個完成健壯的組件設計思路和方法,也能在實現組件的過程逐漸對react/vue的高級知識和技巧有更深的理解和掌握,並且在企業實際工作做遊刃有餘.作為數據驅動的領導者react/vue等MVVM框架的出現,幫我們減少了工作中大量的冗餘代碼, 一切皆組件的思想深得人心.
  • 《精通react/vue組件設計》之實現一個健壯的警告提示(Alert)組件
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言本文是筆者寫組件設計的第七篇文章, 今天帶大家實現一個自帶主題且可關閉的Alert組件, 該組件在諸如Antd或者elementUI等第三方組件庫中都會出現,主要用來提供系統的用戶反饋
  • 精通React/Vue系列之帶你實現一個功能強大的通知提醒框
    正文在開始組件設計之前希望大家對css3和js有一定的基礎,並了解基本的react/vue語法.我們先來解構一下Notification組件, 一個Notification分為以下幾個部分:每一個區塊都可以自定義配置, 也可以組合其他組件.並且我們可以配置提醒框出現的位置,就像antd
  • 如何寫一個vue組件專題及常見問題 - CSDN
    轉自:https://www.cnblogs.com/pengchenggang/p/10880437.html如何寫好一個vue組件一個適用性良好的組件,一種是可配置項很多,另一種就是容易覆寫,從而擴展功能Vue 組件的 API 來自三部分——prop、事件和插槽:prop 允許外部環境傳遞數據給組件event 允許從組件內觸發外部環境的副作用slot
  • Vue3 & React Hooks 新UI組件原理:Modal 彈窗
    然後又無意間刷到「Portal」,才知道Modal的實現還有如此妙的方式,順而想著乾脆把UI組件庫的實現原理看完。1.2 React / Vue早期實現。其實React / Vue早期的實現和Jquery時代的並無二異:「依賴於父節點數據,在當前組件內掛載彈窗。」Vue的情況稍好,有自定義指令這條路走。
  • GitHub上star超1.2k的vue表格組件,功能太多又實用
    組件名稱:vxe-table項目地址:Github:https://github.com/xuliangzhan/vxe-table>碼云:https://gitee.com/xuliangzhan_admin/vxe-table一個基於 vue 的表格組件,支持增刪改查、虛擬滾動、懶加載、快捷菜單、數據校驗、樹形結構、列印導出、表單渲染、數據分頁、模態窗口、自定義模板、賊靈活的配置項、豐富的擴展插件等面向現代瀏覽器
  • React組件之間的8種通訊方式
    2.實例方法在父組件中可以用 refs 引用子組件,之後就可以調用子組件的實例方法了。這是另一種從父組件訪問子組件的方式。3.回調函數方法 1 和 2 介紹了如何把數據從父組件傳給子組件,如果反過來傳值如何做呢?如何把數據從子組件傳給它的父組件?
  • 基於Vue實現一個有點意思的拼拼樂小遊戲
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言為了加深大家對vue的了解和vue項目實戰,筆者採用vue生態來重構此項目,方便大家學習和探索。
  • 又一款基於Vue的數據可視化組件庫,Github上star超1.4k,太酷炫
    組件庫名稱:DataV項目地址:https://github.com/DataV-Team/DataVDataV是一個基於Vue的數據可視化組件庫(當然也有React版本)提供用於提升頁面視覺效果的SVG邊框和裝飾提供常用的圖表如折線圖等飛線圖/輪播表等其他組件npm安裝$ npm install @jiaminghi/data-view使用import
  • 前端組件/庫打包利器rollup使用與配置實戰
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫目前主流的前端框架vue和react都採用rollup來打包,為了探索rollup的奧妙,接下來就讓我們一步步來探索,並基於rollup搭建一個庫打包腳手架,來發布自己的庫和組件。
  • 專欄l 利用數字孿生和創成設計實現單色器狹縫組件的正向設計
    單色器的狹縫是一個關鍵組件,狹縫的開口平行性、對稱性以及開閉的均勻性、狹縫寬度和解析度等指標的精度直接影響單色器的光譜解析度和/或空間分辨能力。特別是最窄的狹縫是決定單色器解析度的關鍵因素。圖2 國外單色器的狹縫組件。來源:安世亞太從拆解測繪到正向設計即使是逆向仿製,水平也有高下之分。對原準產品的拆解測繪仿製是典型的低水平逆向設計活動(如圖3紅色箭頭所示),僅由實物反推到圖紙、反推到設計,而無需反求到原始需求。
  • vuex實現預熱篇-vue插件開發
    #泛舟計劃·讓知識更好看#1.如何引用vue插件呢?Vue.use(Vuex)2.use做了什麼事呢?構造函數和{size:1000} console.log('logger in outputing')}Vue.use(MyLoggerPlugin, {size: 1000})以上就是咱們完成的一個列印的vue插件,是不是很簡單4.一個插件你可以看成是一個組件,一個組件也是一個完成的vue實例,所以vue實例有的他都有// Myplugin作為對象傳入const
  • Vue.js深入學習
    vue.jsv-cloak:解決網速慢閃爍問題 ,不會替換掉標籤裡面的內容v-text:會替換掉標籤裡面的內容:原樣輸出v-html:會解析標籤v-bind:綁定屬性的指令,縮寫,用戶已經可以看到渲染好的頁面了,是實例創建期間的最後一個生命周期函數,當執行完mounted就表示整個Vue實例已經初始化完畢了,此時,組件已經脫離了創建階段進入到了運行階段二 運行階段beforeUpdate() 執行的時候頁面還是舊的,此時data中的數據是新的,頁面尚未和最新的數據保持同步updated(),
  • Vue超好玩的新特性:DOM傳送門
    就像上圖紅框裡的那樣,這是兩個不同的組件,你愛把他倆放哪就放哪,放多遠都沒關係。這麼做完全可以實現,事實上以前我們大家一直都是這樣實現類似需求的。而且如果要是有好幾個輪播圖的話,每個輪播圖都是靠不同的一組按鈕來控制,那麼就會存在很多很多的組件間通信。一方面在 Vuex 中能儘量少定義狀態就儘量少定義。
  • vue 渲染函數插槽專題及常見問題 - CSDN
    這裡的frame組件指的是我們剛才做的組件。// app.vue 在開始和結束frame標記之間的內容將插入到插槽所在的frame組件中,替換slot標記。這是最基本的方法。插槽不是為了一個目的而構建的,或者至少如果它們是,它們已經超越了最初的意圖,成為做許多不同事物的強大工具。可重用的模式組件總是被設計為可重用的,但是某些模式對於使用單個「普通」組件來實施是不切實際的,因為為了自定義它,需要的props 數量可能過多或者需要通過props傳遞大部分內容或其它組件。
  • 我讀完了React的API,並為新手送上了一些建議
    初次接觸 React 的人們都應該從一個高層視角了解下述事實,那就是 React 既非框架也非程式語言,而是一個遵循某些原則的庫;它的開發人員選擇這些原則,是因為他們認為這些原則更適合用來構建響應式和函數式用戶界面。具體的原則包括基於組件的設計、組合優於繼承和自上而下的單向數據流,以在函數響應式編程中保持一致性。
  • Vue 項目中哪些問題戳中你的痛點?你又是如何解決的?(更新中)
    怎麼辦呢,有些小夥伴給第三方組件寫個class,然後在一個公共的css文件中或者在當前頁面再寫一個沒有socped屬性的style標籤,然後直接在裡面修改第三方組件的樣式。這樣不失為一個方法,但是存在全局汙染和命名衝突的問題。約定特定的命名方式,可以避免命名衝突。但是還是不夠優雅。作為一名優(強)秀(迫)的(症)前(患)端(者),怎麼能允許這種情況出現呢?
  • js 設置組件高度 - CSDN
    y)和寬度來進行的,由於輸入控制項的高度基本是固定的。所以不須要設置。在可視化編程沒有出現之前,開發界面算是個苦差事,由於布局是須要花費不少功夫的。比如想要在已經定義好的組件中插入一個組件,那就得又一次改動插入位置下面的組件的坐標。這工作是比較枯燥無聊的。因而,在不是必需的情況下,還是少選擇這樣的布局模式。
  • React 靈魂 23 問,你能答對幾個?
    但是之前數據結構不支持這樣的實現異步 diff,於是 React 實現了一個類似鍊表的數據結構,將原來的 遞歸diff 變成了現在的 遍歷diff,這樣就能做到異步可更新了。和 Function組件?因為 React 要知道當前渲染的是組件還是 HTML 元素。19、redux 是什麼?Redux 是一個為 JavaScript 應用設計的,可預測的狀態容器。