首先讲到这个styled-components就不得不提到css-in-js
css-in-js 有人说这是一种毒药。css挣扎了多年的样式分离在css-in-js上彻底回退 css-in-css以及css-in-js阵营都有很多人争论。 然而我们不用管这些。我将我理解的说一下。
- 面向组件。 从一大堆的Class中挣脱出来,我们可以更专注于组件component上,而不用管繁杂的实现。而事实上我们并不用管实现的细节。这样子更好地利于我们对组件复用组装
css-in-css固然有一大堆的预处理器后处理器,然而我们忽略了javascript,在es6后javascript有了新增模板字符串功能。这简直是就是一剂良药,css应该更好地利用javascript。
取消style跟组件的映射关系 而直接使用props来进行传递,更好地处理css与js的关系。
更好的选择器作用域。 我们知道css划分作用域可以利用简单的类名做作用域切割。但是在组件的层次来说,这样不能显示出最小。
component应该更多的关注于how does it looks not focus in how does it do. container should focus in how does it do.
component应该是一个样式的初始化构造。
对css做单元测试
不足: 1. 学习成本 2. 颠覆 3. 更多的依赖
以下是学习的一些demo
- 标签构造更小的组件
import React, { Component } from 'react'
import styled from 'styled-components'
const Tips = styled.h1`
color:pink;
font-weight:700;
`;
const Container = styled.div`
text-align:center;
width:960px;
height:auto;
margin:'0 auto;
`;
export default class Tip extends Component {
render() {
return (
<Container>
<Tips>Here is styled-components first demo</Tips>
</Container>
)
}
}
- props参数
// 传递参数。首先是像react dom一样传递
import React,{ Component } from 'react'
import styled from 'styled-components'
const Input = styled.input`
padding:8px;
margin:8px;
color:pink;
background:papayawhip;
border:none;
border-radius:3px;
`;
export default class PassedProps extends Component{
render() {
return (
<div>
<Input placeholder = "@mxstbr" type="text" />
<Input value="@geelen" type="text" />
</div>
)
}
}
- 根据props判断
import React,{ Component } from 'react'
import styled from 'styled-components'
//Adapting based on props
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;
`;
export default class ButtonGroupInJs extends Component{
render(){
return (
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
{/* <p>123</p> */}
</div>
)
}
}
- 兼容className
import React,{Component} from 'react'
import styled from 'styled-components'
// styling any components
// 提供样式化的方法更好的为兼容第三方库
// react-native中使用style替代className
const Link = (a)=>{
console.log(a);
const {className,children} = a;
return (<a className = {className}>
{children}
</a>)
}
const StyledLink = styled(Link)`
color:palevioletred;
font-weight:bold;
`;
// 样式化组件总是生成一个真正的类样式表。然后通过className prop将类名传递给React组件(包括第三方组件)。
// styled() ~= styled('tagname') ~= styled.tagname``
export default class StylingComponent extends Component{
render(){
return(
<div>
<Link> boring Link</Link>
<br />
<StyledLink> Styled exciting</StyledLink>
</div>
)
}
}
- 样式扩展继承
import React, { Component } from 'react'
import styled from 'styled-components'
/**
* 以前的样式扩展,往往是将参数传入一个函数 类似mixin之类的处理
* 而在这里 使用更简单的extend来生成另外一个。
* 覆盖了来自初始组件的组件,并保留了初始组件
*/
const Button = styled.button`
color:blue;
font-size:1em;
margin:1em;
padding:0.25em 1em;
border: 2px solid blue;
border-radius:3px;
`;
const GreenButton = Button.extend`
color:green;
border-color:green;
`;
// 不要使用驼峰
export default class ExtendStyleClass extends Component {
render() {
return (
<div>
<Button>normal button</Button>
<GreenButton>extends button</GreenButton>
</div>
)
}
}
- attr构造函数
import React,{Component} from 'react'
import styled from 'styled-components'
// Attaching additional props
// 附加额外的属性
// 主要是.attr(构造函数) 它是一个构造函数。然后再传入模板字符串
const Input = styled.input.attrs({
type:'password',
margin: props=>props.size || '1em',
padding: props=>props.size || '1em'
})`
color : palevioletred;
font-size:1em;
border:2px solid palevioletred;
border-radius:3px;
margin : ${props => props.margin};
padding: ${props=>props.padding};
`
export default class PropsAttach extends Component{
render (){
return (
<div>
<Input placeholder = "A small text input" size="1em" />
<Input placeholder = "A small text input" size="2em"/>
</div>
)
}
}
- 制作动画
import React,{Component} from 'react'
import styled,{keyframes} from 'styled-components'
//利用keyframes生成唯一关键帧动画 然后再使用
const rotate360 = keyframes`
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
`;
const Rotate = styled.div`
display: inline-block;
animation: ${rotate360} 2s linear infinite;
padding: 2rem 1rem ;
font-size: 1.2rem;
`
export default class KeyframsTest extends Component{
render (){
return (
<div>
<Rotate><=-=></Rotate>
</div>
)
}
}
- 支持native端使用