Skip to content

样式深入

React并没有像Vue那样提供特定的区域给我们编写CSS代码,所以你会发现React代码中,CSS样式的写法千奇百怪

内联样式

  • 内联样式优点

    • 内联样式,样式之间不会有冲突
    • 可以动态获取当前state中的状态
  • 内联样式的缺点

    • 写法上都要使用驼峰标识
    • 某些样式没有代码提示
    • 大量的样式,代码混乱
    • 某些样式无法编写(比如伪类、伪元素)

内联样式示例:

jsx

import React from "react";

class App extends React.PureComponent{
    render() {
        return(
           <div>
               <p style={{fontSize:'20px'}}>测试</p>
           </div>
        )
    }
}

export default App

外链样式

将CSS代码写到一个单独的CSS文件中,在使用的时候导入进来

  • 优点:

    • 编写简单,有代码提示,支持所有CSS写法
  • 缺点:

    • 不可以动态获取当前state中的状态
    • 属于全局的css,样式之间会相互影响

示例:

Home.js

jsx

import React from "react";
import "./Home.css"
class Home extends React.PureComponent{
    render() {
        return(
            <div>
                <p>我是段落</p>
                <a href="http://www.28yanyu.cn">我是链接</a>
            </div>
        )
    }
}

export default Home;

Home.css

css

p{
    font-size: 50px;
    color: red;
}

a{
    color: green;
}

如何避免样式之间的相互影响:

  • 第一种方式通过在根节点中设置一个id来控制样式只在一个组件内生效

Home.js

jsx

import React from "react";
import "./Home.css"
class Home extends React.PureComponent{
    render() {
        return(
            <div id={'home'}>
                <p>我是段落</p>
                <a href="http://www.28yanyu.cn">我是链接</a>
            </div>
        )
    }
}

export default Home;

Home.css

css

#home p{
    font-size: 50px;
    color: red;
}

#home a{
    color: green;
}

CSS模块化(推荐)

React的脚手架已经内置了css modules的配置 * .css/.less/.scss 等文件都修改成.module.css/.module.less/.module.scss等

优点: * 编写简单,有代码提示,支持所有css语法 * 解决全局样式互相污染的问题 缺点: * 不可以动态获取当前state中的状态

示例:

Home.js

jsx

import React from "react";
import HomeStyle from './Home.module.css'
class Home extends React.PureComponent{
    render() {
        return(
            <div >
                <p className={HomeStyle.title}>我是段落</p>
                <a href="http://www.28yanyu.cn" className={HomeStyle.link}>我是链接</a>
            </div>
        )
    }
}

export default Home;

Home.module.css

css

.title{
    font-size: 50px;
    color: red;
}

.link{
    color: green;
}

模板字符串

TaggedTemplateLiterals:在使用模板字符串的时候除了可以差值以外,还能调用函数

jsx

// 在JS中处理通过()来调用函数以外,还可以通过模板字符串来调用函数

const name = "test"
const age = 10

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

// test(1,3,4) //[ 1, 3, 4 ]

// test`1,3,4`//[ [ '1,3,4' ] ]

// 通过模板字符串调用函数的规律
/**
 * 参数列表中第一个参数是一个数组,这个数组中保存了所有不是插入的值
 * 参数列表的第二个参数开始,保存的就是所有插入的值
 * 
 * 结论: 
 * 我们可以拿到模板字符串中所有的内容,以及非插入的内容,插入的内容,所以我们就可以对模板字符串的所有的内容进行单独的处理
 */
test`1,3,4,${name},${age}`//[ [ '1,3,4,', ',', '' ], 'test', 10 ]

CSS-In-Js(推荐)

  • 在React中,React认为结构和逻辑是密不可分的,所以在React中结构代码也是通过JS来表写的,正式受到React这种思想的影响, 很多人就开发了用JS编写CSS的库
    • styled-components / emotion
  • 利用JS来编写CSS,可以让CSS具备样式嵌套、函数定义、逻辑复用、动态修改等特性
    • 也就是说,从某种层面上,提供了比过去less/scss更为强大的功能
    • 所以CSS-In-Js,在React中也是比较推荐的一种写法

styled-components使用

安装

shell script

npm i -S styled-components

使用

jsx

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

// 注意点:
// 默认情况下在webstorm中编写styled-components的代码是没有任何提示的
// 如果想有提示就必须安装一个插件`styled-components`
const StyleDiv = styled.div`
    p{
        font-size:50px;
        color:red;
    }
    a{
        font-size:25px;
        color:green
    }
`
class Home extends React.PureComponent{
    render() {
        return(
            <StyleDiv >
                <p >我是段落</p>
                <a href="http://www.28yanyu.cn">我是链接</a>
            </StyleDiv>
        )
    }
}

export default Home;

重要特性

  • props
jsx

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

// 注意点:
// 默认情况下在webstorm中编写styled-components的代码是没有任何提示的
// 如果想有提示就必须安装一个插件`styled-components`
const StyleDiv = styled.div`
    p{
        font-size:50px;
        color:${props=>props.color};
    }
    a{
        font-size:25px;
        color:green
    }
`

class Home extends React.PureComponent{
    constructor(props) {
        super(props);
        this.state = {
            color:'red'
        }
    }

    render() {
        return(
            <StyleDiv color={this.state.color}>
                <p >我是段落</p>
                <a href="http://www.28yanyu.cn">我是链接</a>
                <button onClick={()=>{this.btnClick()}}>按钮12121</button>
            </StyleDiv>
        )
    }
    btnClick(){
        this.setState({
            color:'green'
        })
    }
}


export default Home;

  • attrs
jsx

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

// 调用完attrs方法之后,这个方法返回的还是一个函数,所以我们还可以继续使用模板字符串来调用函数
const StyledInput = styled.input.attrs({
    type:'password'
})``
class Home extends React.PureComponent{
    constructor(props) {
        super(props);
    }

    render() {
        return(
            <StyleDiv>
                <StyledInput/>
            </StyleDiv>
        )
    }
}
export default Home;

  • 如何设置全局的主题

在App.js中引入默认定义好的组件styled-components

jsx
import React from "react";
import { ThemeProvider } from 'styled-components'

import Home from "./components/Home";
class App extends React.PureComponent{
    render() {
        return(
           <ThemeProvider theme={{size:'20px',color:'red'}}>
               <Home/>
           </ThemeProvider>
        )
    }
}

export default App

在Home.js中通过props的方式接收全局传过来的值

jsx

const StyleDiv = styled.div`
    p{
        font-size:${props=>props.theme.size};
        color:${props=>props.theme.color};
    }
    a{
        font-size:25px;
        color:green
    }
`

继承

在编写CSS的时候可能会出现重复的代码,所以需要通过继承来减少代码冗余

jsx

import React from "react";

import styled from 'styled-components'

const StyledDiv1 = styled.div`
font-size: 100px;
color: red;
background-color: blue;
`
const StyledDiv2 = styled.div`
font-size: 100px;
color: green;
background-color: blue;
`

class App extends React.PureComponent{
    render() {
        return(
           <div>
               <StyledDiv1>我是div1</StyledDiv1>
               <StyledDiv2>我是div2</StyledDiv2>
           </div>
        )
    }
}

export default App

上面的代码中样式相同的地方会出现大量的代码冗余,所以经过调整代码,可以通过继承的方式实现减少代码的冗余

jsx

import React from "react";

import styled from 'styled-components'
const BaseDiv = styled.div`
font-size: 100px;
background-color: blue;
`
const StyledDiv1 = styled(BaseDiv)`
color: red;
`
const StyledDiv2 = styled(BaseDiv)`
color: green;
`

class App extends React.PureComponent{
    render() {
        return(
           <div>
               <StyledDiv1>我是div1</StyledDiv1>
               <StyledDiv2>我是div2</StyledDiv2>
           </div>
        )
    }
}

export default App

Released under the MIT License.