React中的CSS——styled-components

Posted 小小白学计算机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React中的CSS——styled-components相关的知识,希望对你有一定的参考价值。

一、认识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;
`

以上是关于React中的CSS——styled-components的主要内容,如果未能解决你的问题,请参考以下文章

Storybook + Ionic React + styled-components CSS 顺序问题

使用styled-components实现CSS in JS

react——css-in-js——styled-components库——定义样式——样式继承——属性传递

styled-component props 不适用于 css

如何理性看待Tailwind和styled-components争宠React

如何理性看待Tailwind和styled-components争宠React