分享三個React組件

簡單介紹三個React組件吧。javascript

  • Image
  • Table
  • Form

React-Image

源碼 Demojava

一個用於加載/預覽圖片的組件react

Image

  • 自動管理圖片的loadingerror狀態, 並顯示不一樣提示.
  • 經過IntersectionObserver來實現圖片懶加載
  • 默認使用Preview來進行圖片預覽
  • 能夠經過group來管理圖片預覽列表, 同一個group的圖片會出如今預覽列表中
import { Image } from '@zzwing/react-image'

<Image src='any.jpg' width='200px' height='200px' onClick={this.onClick}/>
複製代碼

Preview

圖片瀏覽器, 能夠放大/移動/切換等. 已集成到Image中, 能夠經過preview={false}關閉預覽功能. 也能夠直接經過api調用git

import { PreviewApi } from '@zzwing/react-image'
const list = ['1.jpg', '2.jpg', '3.jpg']
// use index
PreviewApi.preview(2, list)
// or use src
PreviewApi.preview('2.jpg', list)
複製代碼

React-Table

源碼 Demogithub

可固定表頭及兩側的表格.chrome

antd的表格

antd的表格也能知足該功能, 但也有幾個不足點(我我的以爲)api

  • 要求每一列都要寫入width用來固定列寬: 經過拆分theadtbody來固定表頭, 經過colgroup來完成列寬的固定
  • 表格高度不能自適應(有可能我使用方式不對?)
  • 還有一點就是antd的表格功能太強大, 有不少功能我是用不上, 無形中增長了代碼.

解決方法

指定表格的scrollTarget, 既滾動的目標, 默認是document.scrollingElement.瀏覽器

  • 當表頭滾動到頂部時, 使用transform固定,因爲屬於同一個table, 這樣能解決tbodythead不對齊的問題.
  • 固定兩側是經過table冗餘實現(antd也是如此), 但只會冗餘須要固定的部分。經過absolute + padding 實現兩側固定.
  • 最後經過不一樣表格的同一行中的最大高度, 來設定其餘表格該行的高度, 來達到高度同步
  • 因爲表格高度超過容器高度, 橫向滾動條會被'隱藏', 所以提供了一個scroller來模擬橫向滾動條, 也就是說任什麼時候候均可以拉動滾動條. (固然也能夠經過shift + 滾輪完成滾動)

不足點

  • 因爲thead使用了transform, 所以也帶來了幾個問題
    • thead設了transform以後, border會失效, 所以使用了box-shadow來模擬border. 固然,
  • 監聽mousewheel來設置transform的時候, 由於滾動和視圖更新有延遲, 在firfoxsafari會有抖動, 在chrome下表現良好.
    • chromefirfox分別加入window.addEventListener('scroll', console.log), 鼠標滾動一次, 會發現ff下會觸發屢次回調, 而chrome只會觸發一次
  • safari下, thead在被固定後的box-shadow會失效.

使用方式

antd相似antd

import { Table } from '@zzwing/react-table'
const data = [{key1: '123', keyn: '123'}]
const columns = [{
    title: 'column1',
    fixed: 'left',
    dataIndex: 'key1'
}, { /* ... */} , {
    title: 'column2',
    fixed: 'right',
    dataIndex: 'keyn'
}]

<Table dataSource={data} columns={columns} rowKey='key1'/>
複製代碼

React-Form-Wrapper

源碼 Demoapp

封裝了onChangevalue的高階組件, 與antdform組件相似 不過只包含最基礎的數據綁定, 也可經過options來自定義數據的讀寫.

import FormWrapperHoc from '@zzwing/react-form-wrapper'

class Test extends React.PureComponent {
  render() {
    const { itemWrapper, getState } = this.props.formWrapper
    const Input = itemWrapper('valueKey', {/* options */})(<input />) const value = getState().valueKey return ( <> {Input} you can get value for {value} </> ) } } 複製代碼

鏈式key的讀寫實現

const Input = itemWrapper('a.b.c.d')(<input />) 複製代碼

按照通常實現, 會經過遍歷每一層來set/get數據.

const _state = {}
const pathArr = path.split('.')
let tmp = _state
pathArr.forEach((each, index) => {
    if(index === pathArr.length - 1) {
        // do something
    }
    if(each in tmp) {
        tmp = tmp[each]
    } else {
        tmp[each] = {}
        tmp = tmp[each]
    }
})
複製代碼

最近改了一種實現方法, 經過一個chain對象直接存儲path對應的數據

Edit chain object

// a.b.c.d
const chain = {
    a: {b: chain['a.b']},
    'a.b': {c: chain['a.b.c']},
    'a.b.c': {d: chain['a.b.c.d']},
    'a.b.c.d': undefined
}
複製代碼
  • 對於get操做, 則能夠直接從chain[path]中獲取數據
  • 對於set操做, 則能夠直接修改chain['a.b.c'].d = 'str', 最後修改chain['a.b.c.d'] = 'str
  • 由於修改的是同一個引用, 因此set操做會同步chain.achain.a.b

最後

antd是一個功能很全的UI庫 但又正由於它功能很全,而大部分我是不須要,無形中可能添加了很多的代碼量 因此我更喜歡是參考antd的實現,去開發知足我的需求的組件 本身開發的組件,本身會更清楚,使用起來更加順手,擴展起來也會很方便 不過對於DatePicker這類組件,我想我仍是直接用antd的吧


但願這幾個組件能幫到你.

相關文章
相關標籤/搜索