React中的CSS——styled-components

  • Post author:
  • Post category:其他




一、认识CSS in JS

实际上,官方文档也有提到过CSS in JS这种方案:


https://zh-hans.reactjs.org/docs/faq-styling.html

  • “CSS-in-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义;
  • 注意此功能并不是 React 的一部分,而是由第三方库提供。 React 对样式如何定义并没有明确态度;

    在这里插入图片描述

在传统的前端开发中,我们通常会将结构(HTML)、样式(CSS)、逻辑(JavaScript)进行分离。

  • 但是在前面的学习中,我们就提到过,React的思想中认为逻辑本身和UI是无法分离的,所以才会有了JSX的语法。
  • 样式呢?样式也是属于UI的一部分;
  • 事实上CSS-in-JS的模式就是一种将样式(CSS)也写入到JavaScript中的方式,并且可以方便的使用JavaScript的状态;

所以React有被人称之为 All in JS;

当然,这种开发的方式也受到了很多的批评:



二、认识styled-components

批评声音虽然有,但是在我们看来很多优秀的CSS-in-JS的库依然非常强大、方便:

  • CSS-in-JS通过JavaScript来为CSS赋予一些能力,包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用、动态修改状态等等;
  • 依然CSS预处理器也具备某些能力,但是获取动态状态依然是一个不好处理的点;
  • 所以,目前可以说CSS-in-JS是React编写CSS最为受欢迎的一种解决方案;

目前比较流行的CSS-in-JS的库有哪些呢?


1. styled-components


2. emotion

3. glamorous

目前可以说styled-components依然是社区最流行的CSS-in-JS库,

所以我们以styled-components的讲解为主:

安装styled-components:

 yarn add styled-components



三、ES6标签模板字符串

ES6中增加了模板字符串的语法,这个对于很多人来说都会使用。 但是模板字符串还有另外一种用法:标签模板字符串(Tagged Template Literals)。

我们一起来看一个普通的JavaScript的函数:

正常情况下,我们都是通过 函数名() 方式来进行调用的,

在这里插入图片描述

其实函数还有另外一种调用方式:

在这里插入图片描述

如果我们在调用的时候插入其他的变量:

  • 模板字符串被拆分了;
  • 第一个元素是数组,是被模块字符串拆分的字符串组合;
  • 后面的元素是一个个模块字符串传入的内容;

    在这里插入图片描述

在styled component中,就是通过这种方式来解析模块字符串,最终生成我们想要的样式的

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    const name = 'zep'
    const age = 18

    function test (...args) {
        console.log(args)
    }

    test(`my name is ${name}, age is ${age}`)
    test`my name is ${name}, age is ${age}`
</script>
</body>
</html>



四、styled的基本使用

styled-components的本质是通过函数的调用,最终创建出一个组件:

  • 这个组件会被自动添加上一个不重复的class;
  • styled-components会给该class添加相关的样式;

    在这里插入图片描述

另外,它支持类似于CSS预处理器一样的样式嵌套:

  • 支持直接子代选择器或后代选择器,并且 直接编写样式;
  • 可以通过&符号获取当前元素;
  • 直接伪类选择器、伪元素等;

    在这里插入图片描述

在这里插入图片描述

import React, {PureComponent} from 'react';
import styled from 'styled-components'

const HomeWrapper = styled.div`
  font-size: 30px;
  color: skyblue;
  
  .banner {
    background-color: darkolivegreen;
    
    span {
      display: flex;
      flex-wrap: wrap;
      color: #fff;
      
      &.active {
        color: #f90;
      }
      
      &:hover {
        color: pink;
      }
      &::after {
        content: 'aaa';
      }
    }
  }
`

const TitleWrapper = styled.h2`
    text-decoration: underline;
    font-size: 18px;
`

class App extends PureComponent {
    render() {
        return (
            <HomeWrapper>
                <TitleWrapper>我是home的标题</TitleWrapper>
                <div className='banner'>
                    <span>轮播图1</span>
                    <span className='active'>轮播图2</span>
                    <span>轮播图3</span>
                    <span>轮播图4</span>
                </div>
            </HomeWrapper>
        );
    }
}

export default App;

在实际项目中的写法:

在这里插入图片描述

在这里插入图片描述



五、styled-components 中的props、attrs属性

  1. props可以穿透

在这里插入图片描述

2. props可以被传递给styled组件

  • 获取props需要通过${}传入一个插值函数,props会作为该函数的参数;
  • 这种方式可以有效的解决动态样式的问题;
  1. 添加attrs属性

    在这里插入图片描述

    在这里插入图片描述

在这里插入图片描述

import React, {PureComponent} from 'react';
import styled from 'styled-components'

const HYInput = styled.input.attrs({
    placeholder: 'zep',
    bColor: 'red'
})`
  background-color: lightblue;
  border-color: ${props => props.bColor};
  color: ${props => props.color}
`

class App extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            color: 'blue'
        }
    }
    render() {
        return (
            <div className="profile">
                <input type="password"/>
                <HYInput type="text" color={this.state.color}/>
                <h2>我是profile的标题</h2>
                <ul className="settings">
                    <li>设置列表1</li>
                    <li>设置列表2</li>
                    <li>设置列表3</li>
                </ul>
            </div>
        );
    }
}

export default App;



六、styled高级特性

  1. 支持样式的继承

    在这里插入图片描述

在这里插入图片描述

  1. styled设置主题

    在这里插入图片描述
import React, {PureComponent} from 'react';
import Home from '../home'
import Profile from '../profile'
import styled, {ThemeProvider} from "styled-components";

const HYButton = styled.button`
    padding: 10px 20px;
    color: red;
    border-color: red;
`
// 继承样式
const HYPrimaryButton = styled(HYButton)`
    //padding: 10px 20px;
    //border-color: red;
    color: #fff;
    background-color: green;
`
/*const HYPrimaryButton = styled.button`
    padding: 10px 20px;
    border-color: red;
    color: #fff;
    background-color: green;
`*/

class App extends PureComponent {
    render() {
        return (
            <ThemeProvider id="app" theme={{themeColor: 'yellow', fontSize: '30px'}}>
                <div>app</div>
                <hr />
                <Home />
                <hr />
                <Profile />
                <HYButton>我是普通的按钮</HYButton>
                <HYPrimaryButton>我是primary的按钮</HYPrimaryButton>
            </ThemeProvider>
        );
    }
}

export default App;

import styled from "styled-components";
export const HomeWrapper = styled.div`
  font-size: 30px;
  color: skyblue;
  .banner {
    background-color: darkolivegreen;
    span {
      display: flex;
      flex-wrap: wrap;
      color: #fff;
      
      &.active {
        color: #f90;
      }
      &:hover {
        color: pink;
      }
      &::after {
        content: 'aaa';
      }
    }
  }
`
export const TitleWrapper = styled.h2`
    text-decoration: underline;
    font-size: 18px;
    color: ${props => props.theme.themeColor};
`



版权声明:本文为weixin_44827418原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。