样式组件(styled-components)

  • 官方文档
  • styled-components是通过JavaScript改变CSS编写方式的解决方案之一,从根本上解决常规CSS编写的一些弊端。通过JavaScript来为CSS赋能,我们能达到常规CSS所不好处理的逻辑复杂、函数方法、复用、避免干扰。样式书写将直接依附在JSX上面,HTMLCSSJS三者再次内聚。*all in js*的思想

基本使用

  1. 安装
npm i styled-components
  1. react项目中引入
import styled from 'styled-components'; // 引入 styled-components
  1. 在项目中书写样式组件
/* ------------------- 某组件 ------------------------- */
import React, { Component } from 'react'
import styled from 'styled-components'; // 引入 styled-components

export default class App extends Component {

render() {
/*
创建一个样式组件(首字母需大写),以 style.元素`样式的书写` 的形式
书写组件样式! 同时支持sass,less等样式预处理器的书写形式
*/
const StyleDIV = styled.div`
background:yellowgreen;
position:fixed;
left:0;
bottom:50%;
width:100%;
height:50px;
line-height:50px;
text-align:center;
ul{
display:flex;
list-style:none;
li{
flex:1;

&:hover{
background:skyblue;
}
}
}
`
return (
<StyleDIV>
<ul>
<li>首页</li>
<li>关于</li>
<li>个人信息</li>
</ul>
</StyleDIV>
)
}
}

结果展示:

image

其他属性

1. 透传

  • 透传属性表示即便原声的标签被styled-components给修改成其他的样式组件,但是原生标签的属性依旧可用,如下:
import React, { Component } from 'react'
import styled from 'styled-components'// 引入styled-components

export default class App extends Component {

render() {
// 创建一个input样式组件
const StyledInput = styled.input`
outline:none;
border-radius:10px;
border-bottom:1px solid red;
`
return (
<div>
{/* 我们仍然可以使用input标签的原生属性,如placeholder等.. */}
<StyledInput type="password" placeholder="输入"/>
</div>
)
}
}

结果展示:

image

2. 基于props做样式判断

  • 我们可以使用类似React中的props的属性,来给封装好的样式组件传值, 通过props属性来控制样式
import React, { Component } from 'react'
import styled from 'styled-components'// 引入styled-components

export default class App extends Component {

render() {
/*
组件样式通过props接收到组件使用者传过来的值
随即可以通过函数返回值的形式修改样式
*/
const StyledDiv = styled.div`
background:${props=>props.bg || 'yellowgreen'};
width:100px;
height:100px;
`
return (
<div>
<StyledDiv bg="skyblue"></StyledDiv>
</div>
)
}
}

结果展示:

image

3. 样式化任意组件(一定要记得className)

  • 在组件间的通信中,我们一样可以使用styled-components来进行样式化组件,比如我们可以在父组件中样式化子组件(给子组件添加样式)
import React, { Component } from 'react'
import styled from 'styled-components' // 引入 styled-components

/* ---------------------------- 父组件 ------------------------------ */
export default class App extends Component {
render() {
/*
接收一个完整的组件,将这个完整的组件包装成样式组件
随机修改其内部的样式
*/
const StyledChild = styled(Child)`
background:yellow;
color:red;
`
return (
<div>
父组件
{/* 使用全新生成样式子组件 */}
<StyledChild/>
</div>
)
}
}

/* ------------------------------- 子组件 ------------------------------ */
function Child(props){
/*
切记 子组件一定要记得设置类名(className)接收样式,
否则样式会不生效!(通过props接收父组件传过来的样式)
*/
console.log('父组件传过来的样式名:',props);
return <div className={props.className}>
子组件
</div>
}

结果展示:

image

4. 样式的继承

  • 有时候我们在编写组件的使用,一些HTML元素的样式是有非常多重叠的,这时我们旧可以使用继承属性来编写样式,高效的复用样式代码
import React, { Component } from 'react'
import styled from 'styled-components' // 引入 styled-components

export default class App extends Component {
/*
样式的复用如下所示: StyledButton 相较于 StyledButton2 和
StyledButton3 只是所需要的背景色不同而已,因此我们可以使用样式的
继承,来达到只修改对应样式,其他样式复用的效果!
*/
render() {
// 按钮1 编写完成所有样式
const StyledButton = styled.button`
width:100px;
height:100px;
background:yellow
`
// 按钮2 基于按钮1的复用样式情况下只修改背景色
const StyledButton2 = styled(StyledButton)`
background:yellowgreen;
`
// 按钮3 基于按钮1的复用样式情况下只修改背景色
const StyledButton3 = styled(StyledButton)`
background:skyblue;
`
return (
<div>
{/* 三个按钮展示 */}
<StyledButton></StyledButton>
<StyledButton2></StyledButton2>
<StyledButton3></StyledButton3>
</div>
)
}
}

结果展示:

image

5. 动画

  • styled-components同样为我们提供了在组件中编写动画的样式功能, 通过而外的引入一个属性(keyframes)来设置对应的动画样式,随即在组件的调用即可!
import React, { Component } from 'react'
// 引入 styled-components 和 动画属性(keyframes)
import styled,{keyframes} from 'styled-components'
export default class App extends Component {
render() {
// 设置动画(使用keyframes属性)
const myaniamtion = keyframes`
from{
transform:rotate(0deg)
}
to{
transform:rotate(360deg)
}
`
// 设置样式组件同时以js变量的形式调用动画
const StyledDiv = styled.div`
width:100px;
height:100px;
background:yellowgreen;
animation: ${myaniamtion} 1s infinite;
`
return (
<div>
<StyledDiv/>
</div>
)
}
}

结果展示:

image