CSS in JS 很棒, 可是如何方便的處理CSS僞類

不知道掘金至不支持GIF

CSS in JS 很棒, 可是如何方便的處理僞類(Pseudo-classes)? react-dom-pseudo 提供一個相似 react-motion 方式的組件,方便的爲 react-dom 對象提供相似 CSS 的僞類.css

咱們首先用 npm 安裝:react

$ npm install --save react-dom-pseudo
複製代碼

APIs

react-dom-pseudo 支持如下僞類:git

Props 模擬僞類 說明 默認值 必須
merge 是否使用 style 和 其餘狀態的 style 進行合併 true
disable 是否取消事件監聽 false
style 默認樣式 undefined
linkStyle :link 未被點擊以前的樣式 undefined
visitedStyle :visited 被點擊過的樣式 undefined
focusStyle :focus input 等類型元素 onFocus 時的樣式 undefined
hoverStyle :hover 鼠標移入時顯示的樣式 undefined
activeStyle :active 鼠標或者觸屏點擊時的樣式 undefined
disableStyle 當取消事件監聽時的樣式 undefined
alwayStyle 會和全部樣式合併,而且覆蓋重複的樣式屬性 undefined

他們會根據事件的觸發,和 style 合併返回, 如 {...style, ...activeStyle}, 只有存在的樣式會進行合併github

樣式的組合規則: {...style, ...linkStyle, ...eventStyle, ...disableStyle, ...alwayStyle}spring

使用

import Pseudo from 'react-dom-pseudo';

export default () => {
  return (
    <div> <div>example:</div> <Pseudo style={sheet.input} hoverStyle={sheet.inputHover} focusStyle={sheet.inputFocus} > {events => <input {...events} />} </Pseudo> </div> ); }; // CSS in js const sheet = { input: { fontSize: '14px', border: '1px solid rgba(0,0,0,0)', background: '#f3f3f3', // 啓用過渡動畫 transition: 'all 0.2s ease-out', }, inputHover: { background: '#f0f0f0', }, inputFocus: { border: '1px solid rgba(0,0,0,0.1)', background: '#f0f0f3', transitionTimingFunction: 'ease-in', }, }; 複製代碼

其中作了什麼?

Pseudo 的 renderProps 中包含如下事件npm

  • onClick: 用來模擬 :link 和 :visited 僞類
  • onFocus\Blur: 用來模擬 :focus 僞類
  • onMouseEnter\Leave: 用來模擬 :hover 僞類
  • onMouseDown\Up: 用來模擬 :active 僞類

若是項目在移動端執行,就會把 onMouse? 相關的事件替換成 onTouch? 以兼容移動端react-native

renderProps 的方式相比我直接定義一個 Input 組件有什麼優點?

咱們先看看若是咱們直接定義一個 Input 組件,來模擬 :hover 僞類數組

// 如下代碼直接在 markdown 中編寫,並沒有通過運行,僅用於闡述觀點
class Input extend React.Component {
  state = {
    hover: false
  }
  handleMouseEnter = ()=>{
    this.setState({ hover: true });
  }
  handleMouseLeave = ()=>{
    this.setState({ hover: false });
  }
  render(){
    return <input style={this.state.hover?{...this.props.style, ...this.props.hoverStyle}:this.props.style} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} /> } } 複製代碼

而後咱們在項目中使用:sass

<Input style={inputStyle} hover={inputHoverStyle} />
複製代碼

一切看起來不錯,可是它不利於擴展, 例如:咱們若是須要給一個 divSignButton 也添加以上功能,咱們須要再寫一個以上組件markdown

固然,咱們也能夠使用 HOC 的方式, 編寫一個 withHover 的組件, 即使如此,也須要在使用以前建立一個新的組件:

const SignButton = withHover(SignButton);
複製代碼

對比之下,就沒有 RenderProps 的方式優雅:

<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
  {events => <input {...events} />} </Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
  {events => <div {...events} />} </Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
  {events => <SignButton {...events} />} </Pseudo>
複製代碼

react-dom-pseudo 還能夠更簡化麼?

因爲若是子對象是一個 div 或是一個 數組 時,以爲使用 childrenFuncion 的意義不大,因此能夠把簡寫:

// 能夠簡寫成以下, 此時 Pseudo 是一個 div組件
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle} />

// 同理,多個子元素,也能夠這樣
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
  <p>多個子元素</p>
  <img src="xxx"/>
  <div>父級至關於一個div</div>
</Pseudo>
複製代碼

我如何獲取 hover、active 等狀態,作除了樣式以外的其餘事件?

renderProps 的參數還有第二個,是 Pseudo 內部的 state, 咱們能夠獲取它以後作其餘事件, 以下面的例子,根據 hover 的狀態咱們修改 divinnerText,

state 有 4 個對象 { hover, focus, active, visited }

<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
  {(events, state) => {
    const mouseState = state.hover ? 'mouseIn' : 'mouseOut';
    return <div {...events}>{mouseState}</div>;
  }}
</Pseudo>
複製代碼

如何臨時屏蔽事件監聽?

Pseudo 把 disable 設置成 true

<Pseudo disable />
複製代碼

如何在全部狀態樣式的外層添加樣式?

Pseudo 有一個 alwayStyle 屬性,最終返回的樣式是這樣的 {...style, ...otherStyle, ...alwayStyle}

<Pseudo alwayStyle={style} />
複製代碼

CSS in JS 好用麼?

因人而異,我以爲比寫 csssass 更好一些,其緣由有如下幾點:

  1. 許多動畫庫,如 react-motion, react-spring 等,都會須要操做 style 對象, 它的樣式可能分別會存在 css 和 js 中,此時就沒有 CSS in JS 簡潔;
  2. CSS in JS 可讓組件相關的代碼在一個文件裏閉合,咱們修改一個組件時,不須要來回切換文件;
  3. 若是咱們項目較大,須要切分模塊,CSS in JS 會比傳統的 css 文件更好和組件一塊兒切分.

如何解決一些 CSS in JS 寫起來麻煩的事情?

  1. sass 的顏色混合等功能,能夠使用 mix-color 之類的庫輕鬆解決;
  2. sass 的自定義變量,在 CSS in JS 中能夠很輕鬆的定義一個 globalStyles 對象達到;
  3. css 的僞類,之前用組件 state 的寫法編寫起來比較麻煩、重複,能夠用 react-dom-pseudo 解決.

react-dom-pseudo 支持 react-native 嗎?

因爲 react-dom-pseudo 用到了 ReactDOM 的事件,因此不支持 react-native, 有須要的朋友能夠 fork 一份把DOM事件改爲RN的 touchble 事件

最後,謝謝閱讀:)

MIT License

相關文章
相關標籤/搜索