mopduan / team

Team技术总结
MIT License
40 stars 7 forks source link

styled-components 样式组件 #24

Open MayOMengxuhui opened 6 years ago

MayOMengxuhui commented 6 years ago

styled-components

背景

import React from 'react';
import styled from 'styled-components'; 

const Title = styled.h1`
    font-size: 1.5em;
    text-align: center;
    color: red;
`;

class App extends React.Component {
    render() {
        return (
            <Title>Hello styled--components</Title>
        )
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
);

示例: 1522579578467 上例中的styled.h1是一个标签模板函数,紧跟其后的是一个模板字符串参数,“标签模板”和“模板字符串”都是es6的语法。styled.h1函数返回一个React Component,styled components会为这个React Component添加一个class,该class的值为一个随机字符串。传给styled.h1的模板字符串参数的值实际上是CSS语法,这些CSS会附加到该React Component的class中,从而为React Component添加样式。

1522581565973

props参数控制样式

1522582460455 styled components的写法中样式组件暴露props让外层JS来控制样式,不再需要className或style这样的“中间人”,移除了样式和组件间的映射关系。

CSS作用域

export class App extends React.Component { render() { return (

<div className="content1">content1-style</div> <div className="content2">content2-style</div>
    )
}

}

 示例
![1522584049702](https://user-images.githubusercontent.com/32735787/38172912-6bc92bd4-35e7-11e8-9d08-95169d83e272.jpg)

### 组件样式继承
 - 通常在 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; ;

export class App extends React.Component { render() { return (

) } } ``` 示例 ![1522584610585](https://user-images.githubusercontent.com/32735787/38172990-ecbbc494-35e8-11e8-8fb8-f9d590f2b5aa.jpg) ![1522584703345](https://user-images.githubusercontent.com/32735787/38172995-f815a864-35e8-11e8-910d-c56b225e2bc5.jpg) 我们可以看到在原生的样式和组件之间是多对多的映射关系,styled-components 通过继承彻底的移除了这种只为了样式而存在映射关系。组件内部会执行类似于对象合并的操作,子组件中的属性会覆盖父组件中同名的属性。 ### styled-components中的 `attrs` styled-components 同时支持为组件传入 html 元素的其他属性,比如为 input 元素指定一个 type 属性,我们可以使用 attrs 方法来完成: ``` const Password = styled.input.attrs({ type: 'password' })` border: 1px solid #ccc; padding: 7px 0px; border-radius: 3px; padding-left:5px; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); box-shadow: inset 0 1px 1px rgba(0,0,0,.075); -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; `; export class App extends React.Component { render() { return ( ) } } ``` 示例 ![1522585836037](https://user-images.githubusercontent.com/32735787/38173152-955e6b04-35eb-11e8-9274-adafbd479081.jpg) 在实际开发中,这个方法还有一个有用处,用来引用第三方类库的 css 样式和自己定义的类名: ``` const Row = styled.div.attrs({className: "row"})` color: palevioletred; font-size: 1em; margin: 1em; ` export class App extends React.Component { render() { return ( hello styled-components ) } } ``` 示例 ![1522586415021](https://user-images.githubusercontent.com/32735787/38173221-06c13d20-35ed-11e8-8497-638c213a7bc8.jpg) ### theme 特性 - styled-components 里面还有一个比较特别的特性是theme,它利用了 React 的context特性来传递其中的参数,可以让样式对象直接从最上层的组件传递到最下层的组件。 ``` const Box = styled.div` color: ${props => props.theme.color}; `; export class App extends React.Component { render() { return ( sI'm mediumseagreen! ) } } ``` 示例 ![1522587877797](https://user-images.githubusercontent.com/32735787/38173387-510ed4a2-35f0-11e8-8da4-5de34d19baff.jpg) ### 独立样式文件 在一般的 React 组件中,样式和组件文件是分离的(比如 App.js 和 style.css),使用了 styled-components 后其实也可以沿用这种方式来组织文件,定义一个style.js文件来写样式对象,然后在组件文件中引入该样式文件。 ``` // style.js import styled from 'styled-components'; export const AppDiv = styled.div` color: palevioletred; font-size: 1em; margin: 1em; `; // App.js import React from 'react'; import * as css from './style'; export class App extends React.Component { render() { return ( Hello styled-components ) } } ``` ### 总结 1. 可以在样式定义中直接引用到 js 变量,共享变量,非常便利; 2. 支持组件之间继承,方便代码复用,提升可维护性; 3. 兼容现有的 className 方式,升级无痛; 参考链接: [https://www.styled-components.com/](https://www.styled-components.com/)
kmvan commented 5 years ago

这篇文章有点老了,现在已经不使用 .extend 这个方法了。