专栏名称: 前端外刊评论
最新、最前沿的前端资讯,最有深入、最干前端相关的技术译文。
目录
相关文章推荐
商务河北  ·  经开区“美•强•优”三重奏 ·  16 小时前  
前端早读课  ·  【第3451期】前端 TypeError ... ·  3 天前  
51好读  ›  专栏  ›  前端外刊评论

使用 styled-components 加速 React 开发

前端外刊评论  · 公众号  · 前端  · 2017-08-29 16:32

正文

styled-components 是一个常用的 css in js 类库。和所有同类型的类库一样,通过 js 赋能解决了原生 css 所不具备的能力,比如变量、循环、函数等。诸如 sass&less 等预处理可以解决部分 css 的局限性,但还是要学习新的语法,而且需要对其编译,其复杂的 webpack 配置也总是让开发者抵触。而 styled-componens 很好的解决了这些问题,很适合 React 技术栈的项目开发。

安装和使用

下面我们看一个简单的示例:

$ npm install styled-components
$ yarn add styled-components

我们可以用自己喜欢的方式将包安装到本地,然后就可以在项目中直接使用它:

import styled from 'styled-components';const Wrapper = styled.section`  margin: 0 auto;  width: 300px;  text-align: center;`;const Button = styled.button`  width: 100px;  color: white;  background: skyblue;`;render(
  <Wrapper>
    <Button>Hello World</Button>
  </Wrapper>);

上述的代码片段展示了 React 项目中使用 styled-components,定义了 Wrapper 和 Button 两个组件,包含了 html 结构和对应的 css 样式,从而将样式和组件之间的 class 映射关系移除。这种用法的学习成本还是很少的,在实际应用中我们完全可以将 style 和 jsx 分开维护。

组件和容器

在 styled-components 中, 将最简单只包含样式的结构称为组件(components),将包含业务逻辑或者复杂生命周期方法(无样式)的称之为容器(containers)。同时,将组件和容器分离开。

  • Components = How things look

  • Containers = How things work

下面的 2 个代码片段简单的说明了是否使用 styled-components 的区别:

1.没有使用 styled-components

class Sidebar extends React.Component {
  componentDidMount() {
    fetch('/url')
      .then(res => {
        this.setState({
          items: res.items,
        })
      })
  }
  render() {
    return (
      <div classNames="sidebar">
        {this.state.items.map(item => (
          <div className="sidebar__item">{item}</div>
        ))}
      </div>
    );
  }}

2. 使用 styled-component

class SidebarContainer extends React.Component {
  componentDidMount() {
    fetch('/url')
      .then(res => {
        this.setState({
          items: res.items,
        })
      })
  }
  render() {
    return (
      <Sidebar>
        {this.state.items.map(item => (
          <SidebarItem>{item}</SidebarItem>
        ))}
      </Sidebar>
    );
  }}

基于 props 定制主题

下面来看一下使用 styled-components 来定义组件的主题。

const Button = styled.button`  background: ${props => props.primary ? 'palevioletred' : 'white'};  color: ${props => props.primary ? 'white' : 'palevioletred'};  font-size: 1em;  margin: 1em;  padding: 0.25em 1em;  border: 2px solid palevioletred;  border-radius: 3px;`;render(
  <div>
    <Button>Normal</Button>
    <Button primary>Primary</Button>
  </div>);

我们在组件中传入的所有 props 都可以在定义组件时获取到,这样就可以很容易实现组件主题的定制。如果没有 styled-components 的情况下,需要使用组件 style 属性或者定义多个 class 的方式来实现。

组件样式继承

通常在 css 中一般会通过给 class 传入多个 name 通过空格分隔的方式来复用 class 定义,类似 class="button tomato"。在 styled-components 中利用了 js 的继承实现了这种样式的复用:

const Button = styled.button` 
color: palevioletred;

font-size: 1em;

margin: 1em;

padding: 0.25em 1em;

border: 2px solid palevioletred;

border-radius: 3px;
`;
const TomatoButton = Button.extend`  
color: tomato;

border-color: tomato;
`;

我们可以看到在原生的样式和组件之间是多对多的映射关系,styled-components 通过继承彻底的移除了这种只为了样式而存在映射关系。组件内部会执行类似于对象合并的操作,子组件中的属性会覆盖父组件中同名的属性。

组件内部使用 className

在日常开发中总会出现覆盖组件内部样式的需求,你可能想在 styled-components 中使用 className,或者在使用第三方组件时。看下面的示例:

<Wrapper>
  <h4>Hello Wordh4>
  <div className="detail">div>
Wrapper>

对于这种 styled-components 和 className 混用,或者是一些伪类的情况同样是支持的:

import styled from 'styled-components';
const Wrapper = styled.div`
   display: block;
   h4 {
       font-size: 14px;
       &:hover {
          color: #fff;
       }
    }

   .detail {
   color: #ccc;  }
`;

当然还可以通过 injectGlobal 的方式将通用的样式注入到全局中:

import styled, { injectGlobal } from 'styled-components';
injectGlobal`
@font-face {
   font-family: 'Operator Mono';
   src: url('../fonts/Operator-Mono.ttf');
}
body {
  margin: 0;

}
`;

组件中维护其他属性







请到「今天看啥」查看全文