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

相关文章
相关标签/搜索