React學(xué)習(xí)(10)-React中編寫(xiě)樣式CSS(styled-components)

前言

React中編寫(xiě)樣式css(styled-components).png

React是一個(gè)構(gòu)建用戶(hù)界面的js庫(kù),從UI=render()這個(gè)等式中就很好的映射了這一點(diǎn),UI的顯示取決于等式右邊的render函數(shù)的返回值.

而編寫(xiě)React應(yīng)用,就是在編寫(xiě)React組件,組件中最重要的數(shù)據(jù)就是props和state,有了數(shù)據(jù),怎么讓其以什么樣的顯示,那就是CSS做的事情了

在React中,一切皆可以是Js,也就是說(shuō)在js里面可以寫(xiě)css,這相比傳統(tǒng)的內(nèi)容(html),層疊樣式(css),行為動(dòng)作(js)進(jìn)行分離,這種分離僅僅是把三個(gè)不同的技術(shù)進(jìn)行了物理上的分離,進(jìn)行分開(kāi)管理,如果從另一個(gè)視覺(jué)角度上講,并沒(méi)有實(shí)現(xiàn)高內(nèi)聚的特點(diǎn)

既然前端本身就是頁(yè)面的展示,那么把js和css放在一起,也是一種細(xì)粒度的組合,css也可以和Js一樣,通過(guò)模塊化的形式嵌入到j(luò)s里面去

CSS modules很好的解決了樣式?jīng)_突,利用了分而治之的理念,在如今組件化開(kāi)發(fā)大行其道上,同樣css也在不斷的進(jìn)化,如同js一樣,也有變量,函數(shù)等具備Js一樣的活力,那么在React中是怎么實(shí)現(xiàn)樣式的模塊化的?

  • 通過(guò)單獨(dú)的*.css文件定義組件的樣式,并且通過(guò)clssName指定他們,有什么不好的?

  • 在JSX上進(jìn)行事件的監(jiān)聽(tīng)綁定,通過(guò)on*EventType只針對(duì)原生的HTML標(biāo)簽起作用的,如果是自定義的組件,是不起作用的,有什么好的解決辦法?

  • 樣式化組件的魅力(特點(diǎn))

那么本節(jié)就是你想要知道的

如果想閱讀體驗(yàn)更好,戳該鏈接,React中編寫(xiě)樣式css(styled-components)

React中組件形式

關(guān)于React中定義組件的形式,有如下幾種方式,其中前兩個(gè)在之前的學(xué)習(xí)當(dāng)中,相信你已經(jīng)很熟悉了的,如果不清楚,可以查看前面的內(nèi)容的

  • 類(lèi)class聲明的組件(類(lèi)組件/容器組件)

  • 函數(shù)式聲明的組件(函數(shù)組件/無(wú)狀態(tài)組件/UI組件)

  • 樣式化組件(styled-components)

本節(jié)主要講的就是樣式化組件,給一個(gè)React組件添加樣式,有哪些方式?下面一起來(lái)看看的

行內(nèi)樣式 VS 外部樣式

想要給React組件添加樣式,常見(jiàn)的方式有

  • 在JSX上添加style屬性定義行內(nèi)樣式

  • 通過(guò)import關(guān)鍵字引入外部樣式

像如下所示,在JSX上添加樣式: 下面的代碼是用class類(lèi)組件聲明了一個(gè)Header組件,這個(gè)組件返回了一個(gè)button按鈕,給這個(gè)按鈕通過(guò)style添加了一些樣式

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';

class Header extends Component {
  render(){
    return (
      <Fragment>
        <button style = {{ width: '100px', height: '40px', borderRadius: '3px', outline: 'none', outline: 'none', border: 'none', cursor: 'pointer', background: '#abcdef', color: '#fff'}}>button按鈕</button>
      </Fragment>
    );
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Header   />, container);

對(duì)于上面的行內(nèi)樣式,也可以把它定義成一個(gè)對(duì)象Object的方式去定義樣式,與下面是等價(jià)的

class Header extends Component {
  render(){
    const btnStyle = {
      width: '100px',
      height: '40px',
      borderRadius: '3px',
      outline: 'none',
      border: 'none',
      cursor: 'pointer',
      background: '#abcdef',
      color: '#fff'
    }
    return (
      <Fragment>
             <button style = { btnStyle }>button按鈕</button>
      </Fragment>
    );
  }
}

雖然這樣也是在JS中寫(xiě)css樣式,但是管理起來(lái)并不方便,很多時(shí)候,我們是用clssName的方式去定義樣式的 ,按照我們熟悉的方式,就是把樣式文件命名成*.css,然后通過(guò)import的方式給引入進(jìn)去

import "./style.css";

對(duì)于樣式名,有時(shí)候,對(duì)于各個(gè)不同的組件的className有可能會(huì)一樣,如果是這樣的話(huà),后面引入的樣式名會(huì)覆蓋前面的,這樣的話(huà)顯然不是我們想要的結(jié)果了

那有什么好的解決辦法?

在React中有css-in-js,它是一種模式,這個(gè)css由js生成而不是在外部文件中定義,是CSS Modules,主要是借助第三方庫(kù)生成隨機(jī)類(lèi)名稱(chēng)的方式來(lái)建立一種局部類(lèi)名的方式

這種css-in-js的第三方模塊有很多:可以訪(fǎng)問(wèn):https://github.com/MicheleBertoli/css-in-js

今天的主要學(xué)習(xí)的是github上star數(shù)最多的,styled-components

使用styled-components的好處是:它可以讓組件自己的樣式對(duì)自己生效,不是全局生效,做到互不干擾

首先你得通過(guò)npm或者cnpm進(jìn)行安裝styled-components模塊

npm install -S styed-components

在安裝完后,在使用styled-components的文件內(nèi),通過(guò)import的方式引入該模塊

如下代碼所示: 在文件的上方引入styled-components,實(shí)例化了一個(gè)styled對(duì)象,通過(guò)給styled對(duì)象下添加你想要的html元素,利用了Es6中的一個(gè)模板字符串,反引號(hào)

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import styled from "styled-components"; // 引入styled-components庫(kù),實(shí)例化styled對(duì)象

// 聲明樣式ButtonA組件,通過(guò)styled對(duì)象進(jìn)行創(chuàng)建,注意styled.html元素,后面是反引號(hào)
const ButtonA = styled.button`
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
  background: #abcdef;
  color: #fff;
`;

// 樣式化聲明ButtonB組件
const ButtonB = styled.button`
  background: red;
  color: #fff;
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
`;

class Header extends Component {
  render(){
    return (
      <Fragment>
             <ButtonA>按鈕A</ButtonA>
             <ButtonB>按鈕B</ButtonB>
      </Fragment>
    );
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Header   />, container);

這是渲染的結(jié)果:

樣式化組件.png

注意:要避免在render方法中聲明樣式化組件 如下所示:這樣程序雖然不報(bào)錯(cuò),但是會(huì)引起性能問(wèn)題,引起組件不必要的渲染

下面這種做法是不推薦的,應(yīng)當(dāng)避免使用

class Header extends Component {
  render() {
    const ButtonA = styled.button`
      width: 100px;
      height: 40px;
      border-radius: 3px;
      outline: none;
      border: none;
      cursor: pointer;
      background: #abcdef;
      color: #fff;
`;

    // 聲明樣式ButtonB組件,不應(yīng)該在render函數(shù)里面聲明樣式組件
  const ButtonB = styled(ButtonA)`
      background: red;
`;
    return (
      <Fragment>
        <ButtonA>按鈕A</ButtonA>
        <ButtonB>按鈕B</ButtonB>
      </Fragment>
    );
  }
}

因?yàn)樵趓ender方法中聲明樣式化組件,每次都會(huì)動(dòng)態(tài)渲染創(chuàng)建一個(gè)新的組件升略。這意味著React必須在每個(gè)后續(xù)渲染中丟棄并重新計(jì)算DOM樹(shù)的那部分廷区,而不是僅計(jì)算它們之間發(fā)生變化的差異列疗。這會(huì)導(dǎo)致性能瓶頸

正確的做法就是如同剛開(kāi)始那樣,把樣式組件放到組件最外面去

當(dāng)然,為了便于樣式的集中管理,對(duì)于樣式化組件,我們往往會(huì)把它寫(xiě)在一個(gè)文件中去,把上面的樣式組件放到一個(gè)style.js的文件中去,然后通過(guò)Es6中模塊化的export的方式對(duì)外暴露出去,只要哪個(gè)組件模塊需要,直接通過(guò)import引入即可

import styled from "styled-components"; // 引入styled-components

// 聲明樣式ButtonA組件
const ButtonA = styled.button`
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
  background: #abcdef;
  color: #fff;
`;

// 聲明樣式ButtonB組件
const ButtonB = styled.button`
  background: red;
  color: #fff;
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
`;

// 對(duì)外暴露出去
export {
    ButtonA,
    ButtonB
}

細(xì)心的朋友你會(huì)發(fā)現(xiàn),其實(shí)兩個(gè)按鈕有很多相同的樣式,只有背景顏色不一樣而已,如果重復(fù)寫(xiě)很多樣式,那么肯定是有很多冗余的代碼,styled-components中提供了繼承的能力

要?jiǎng)?chuàng)建一個(gè)繼承另一個(gè)樣式的新組件,只需將其包裝在styled(繼承的組件)構(gòu)造函數(shù)中即可,如下所示

// 聲明樣式ButtonA組件
const ButtonA = styled.button`
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
  background: #abcdef;
  color: #fff;
`;

// 聲明樣式ButtonB組件,同時(shí)樣式ButtonB組件繼承了ButtonA組件的樣式,又給自身拓展了樣式,更改了自身的背景色
const ButtonB = styled(ButtonA)`
  background: red;
`;

在要使用樣式組件的地方通過(guò)import引入ButtonA,ButtonB組件

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import {
  ButtonA,
  ButtonB
}
from './style'



class Header extends Component {
  render(){
    return (
      <Fragment>
          <ButtonA>按鈕A</ButtonA>
          <ButtonB>按鈕B</ButtonB>  
      </Fragment>
    );
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Header   />, container);

樣式組件可以接收props

對(duì)于組件外部定義的屬性,在樣式組件內(nèi)可以進(jìn)行接收,寫(xiě)一些簡(jiǎn)單的邏輯表達(dá)式 如下所示:在確定按鈕組件內(nèi)設(shè)置了一個(gè)color屬性,在樣式組件內(nèi)可以通過(guò)props進(jìn)行接收

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import {
  Button
}
from './style'

class Header extends Component {

  render() {
    return (
      <Fragment>
        <Button>取消</Button>
        <Button color="red">確定</Button>
      </Fragment>
    );
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Header />, container);

在樣式組件內(nèi),屬性值可以通過(guò)Es6中的插值表達(dá)式,${表達(dá)式}的方式進(jìn)行指定的邏輯判斷,達(dá)到自己想要的目的

import styled from "styled-components"; // 引入styled-components

// 聲明樣式Button組件
const Button = styled.button`
  width: 100px;
  height: 40px;
  border-radius: 3px;
  outline: none;
  border: none;
  cursor: pointer;
  background: ${props => props.color ? "red": '#fff'};
  color: ${(props) => props.color ? '#fff': 'red'};
  border: 2px solid red;
  margin-right: 15px;
`;


// 對(duì)外暴露出去
export {
    Button
}

渲染的結(jié)果如下所示


樣式化組件接收參數(shù).png

這里只是為了說(shuō)明在樣式化組件內(nèi)部可以接收props值,有時(shí)候,在一些場(chǎng)景下是很有用的

例如:自己封裝一些自己組件,不同大小按鈕等等的,通過(guò)在組件外部設(shè)置屬性值,然后在樣式組件內(nèi)部進(jìn)行接收,控制組件的樣式UI形態(tài)

當(dāng)然這種簡(jiǎn)單的樣式處理,完全是可以用上面繼承的方式去處理的

值得注意的是,在插入背景圖片時(shí),是不支持直接插入的,這樣是不生效的

const Content = styled.div`
    width: 550px;
    height: 290px;
    background:url('./react.jpg');
`;

引入本地圖片必須得通過(guò)定義變量的方式來(lái)實(shí)現(xiàn),如下所示

import BgImg from './react.jpg'; // 將圖片定義成一個(gè)變量的方式來(lái)引用

const Content = styled.div`
    width: 550px;
    height: 290px;
    background: url(${BgImg}); // 注意這里用Es6中的模板語(yǔ)法
`;

.attrs方法支持給組件添加屬性

attrs是一個(gè)構(gòu)造方法,可以給樣式組件添加自身的額外屬性(這個(gè)屬性只允許html標(biāo)簽原生自有的屬性),不支持自定義屬性,要想添加自定義屬性,只能在jsx元素上進(jìn)行添加

attrs可接收兩種類(lèi)型的參數(shù):

  • 參數(shù)可以接收一個(gè)對(duì)象,通過(guò)它添加的屬性,會(huì)被合并到樣式組件當(dāng)中去

  • 參數(shù)可以是一個(gè)函數(shù),如果有props值,則可使用該模式 如下代碼所示

import styled from "styled-components"; // 引入styled-components

// 參數(shù)是一個(gè)對(duì)象
const Input = styled.input.attrs({
      placeholder: '請(qǐng)輸入信息',
      type: 'text'
      
  })`
    width:${props => props.width};
    height: ${props => props.size === 'small'? '24px': '40px'};
    font-size: 14px;
    text-indent: 10px;
    border-radius: 3px;
    border: 1px solid palevioletred;
    display: block;
    margin: 0 0 1em;
  
    ::placeholder {
      color: palevioletred;
    }
  `

// 對(duì)外暴露出去
export {
    Input
}

在要引用組件處

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';

import {
  Input
}
from './style'

class Header extends Component {

  render() {
    return (
      <Fragment>
         <Input width="150px" placeholder="請(qǐng)輸入賬號(hào)" size="small"/>
         <Input width="200px" placeholder="請(qǐng)輸入密碼" size='large' type="password" />
      </Fragment>
    );
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Header />, container);

渲染結(jié)果如下所示:


attrs.png

如果有參數(shù)可以將樣式組件寫(xiě)成下面這樣,attrs內(nèi)可接收一個(gè)函數(shù),并且通過(guò)props接收外部的屬性值

const Input = styled.input.attrs(props => ({ // 參數(shù)是一個(gè)函數(shù),可以通過(guò)props進(jìn)行接收
    placeholder: '請(qǐng)輸入信息',
    type: 'text'
}))`
    width:${props => props.width};
    height: ${props => props.size === 'small'? '24px': '40px'};
    // 如下省略
  `

注意:關(guān)于樣式的優(yōu)先級(jí)

行內(nèi)樣式>外部樣式(樣式組件),如果行內(nèi)元素設(shè)置的了默認(rèn)值,則行內(nèi)樣式優(yōu)先

否則,在attrs內(nèi)設(shè)置的屬性會(huì)覆蓋外部的屬性

至于什么時(shí)候用attrs

使用attrs將屬性傳遞給樣式化組件

當(dāng)你希望樣式化組件的每個(gè)實(shí)例都具有該prop時(shí)使用attrs赘艳,換句話(huà)說(shuō),通過(guò)attrs設(shè)置的屬性,它是公共的,如果每個(gè)實(shí)例需要不同的實(shí)例時(shí)則可直接傳遞props

如何覆蓋默認(rèn)樣式

有時(shí)候,需要覆蓋樣式最粗魯?shù)姆绞骄褪窃趯傩院竺婕訖?quán)重,通過(guò)丁稀!important來(lái)完成应民,但這很容易出錯(cuò),并且很容易出問(wèn)題

具體的實(shí)現(xiàn)方式是通過(guò)&符號(hào)的方式,每添加一個(gè)&符號(hào),都會(huì)隨機(jī)生成一個(gè)類(lèi)樣式

const ButtonB = styled(ButtonA)`
  &&& {
    color: palevioletred;
    font-weight: bold;
  }
`

如下圖所示


如何覆蓋默認(rèn)樣式.png

如何覆蓋內(nèi)聯(lián)樣式

內(nèi)聯(lián)樣式的優(yōu)先級(jí)是最高的,始終優(yōu)先于外部CSS话原,因此無(wú)法通過(guò)簡(jiǎn)單地樣式組件覆蓋它,但是有具體的解決辦法的, 就是使用&[style]和!important加權(quán)重的方式

有時(shí)候,如果在JSX上聲明了行內(nèi)樣式,但是外部想要覆蓋它,那么這個(gè)時(shí)候,&[style]和import加權(quán)重的方式就很有用了的,但是在實(shí)際開(kāi)發(fā)中,應(yīng)該避免使用行內(nèi)樣式,在這里只是為了說(shuō)明諸如此類(lèi)的解決辦法

const ButtonB = styled(ButtonA)`
  &[style]{
    background: blue !important;
    font-weight: bold;
   }
 
`;

同樣诲锹,每追加一個(gè)&符號(hào),都會(huì)新添加一個(gè)類(lèi),在實(shí)際的項(xiàng)目中,應(yīng)當(dāng)少用行內(nèi)樣式的,不要一時(shí)爽,后面給自己挖坑的

重置全局樣式

對(duì)于React中重置默認(rèn)樣式,它使用的是createGlobalStyle這個(gè)函數(shù),需要從styled-components中注入 如下所示:

import { createGlobalStyle } from 'styled-components'

const globalStyle = createGlobalStyle`
   html, body, div, span, applet, object, iframe,
        h1, h2, h3, h4, h5, h6, p, blockquote, pre,
        a, abbr, acronym, address, big, cite, code,
        del, dfn, em, img, ins, kbd, q, s, samp,
        small, strike, strong, sub, sup, tt, var,
        b, u, i, center,
        dl, dt, dd, ol, ul, li,
        fieldset, form, label, legend,
        table, caption, tbody, tfoot, thead, tr, th, td,
        article, aside, canvas, details, embed,
        figure, figcaption, footer, header, hgroup,
        menu, nav, output, ruby, section, summary,
        time, mark, audio, video {
            margin: 0;
            padding: 0;
            border: 0;
            font-size: 100%;
            font: inherit;
            vertical-align: baseline;
        }
        article, aside, details, figcaption, figure,
        footer, header, hgroup, menu, nav, section {
            display: block;
        }
        body {
            line-height: 1;
        }
        ol, ul {
            list-style: none;
        }
        blockquote, q {
            quotes: none;
        }
        blockquote:before, blockquote:after,
        q:before, q:after {
            content: '';
            content: none;
        }
        table {
            border-collapse: collapse;
            border-spacing: 0;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: sans-serif;
        }

`
export default globalStyle;

一般而言,把重置樣式單獨(dú)的定義成一個(gè)文件,單獨(dú)的引入到index.js當(dāng)中去的,全局生效的

需要注意的是:在早先的版本中使用全局的方式是injectGlobal,而這個(gè)API已經(jīng)廢棄,并由styled-components v4中的createGlobalStyle替換了

CSS-module編寫(xiě)樣式

在使用create-react-app腳手架創(chuàng)建的項(xiàng)目后,該項(xiàng)目是支持css-module的

但是需要注意以下幾點(diǎn):

  • 樣式文件的名稱(chēng)必須以xxx.module.css或者xxx.module.scss的形式命名:例如styles.module.css或者styles.module.scss

  • 以變量的形式導(dǎo)入樣式文件,比如:import styles from './style.module.css',如果是直接導(dǎo)入xxx.css,在JSX元素上的className的屬性名稱(chēng),是無(wú)法通過(guò)變量對(duì)象引入樣式的,如果是直接引入樣式,則在className的屬性值中直接引入類(lèi)名即可

  • className以變量引用的方式進(jìn)行添加,例如:className ={styles.counter}

  • 使用sass時(shí),腳手架創(chuàng)建的項(xiàng)目,默認(rèn)是支持sass的,使用時(shí)只需要安裝一下node-sass這個(gè)包即可

在根文件夾下定義styles.module.css文件,寫(xiě)入如下幾行樣式代碼

.counter{
    text-align: center;
}

.button{
    padding: 0 10px;
}

.spanText{
    padding: 0 15px;
}

在使用css-module樣式的文件內(nèi),通過(guò)import的方式引入該xxx.module.css文件

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import styles from './styles.module.css'; // 引入styles.module.css,實(shí)例化一個(gè)styles對(duì)象

class Counter extends Component {
  constructor(props){
    super(props);

    this.state = {
      count: 0
    }
  }

  increment = () => this.setState({ count: this.state.count + 1 })
  decrement = () => this.setState({ count: this.state.count - 1 })

  render() {
    return (
      <Fragment>
        <div className={styles.counter}>
            <button className={styles.button} onClick={this.decrement}>
            -
               </button>
              <span className={styles.spanText}>{this.state.count}</span>
           <button className={styles.button} onClick={this.increment}>
              +
              </button>
        
        </div>
      </Fragment>

    )
  }
}


const container = document.getElementById('root');

ReactDOM.render(<Counter />, container);

具體效果如下所示:


數(shù)字加減成樣式組件.gif

對(duì)于以上的寫(xiě)法,是我們?cè)赗eact中常見(jiàn)的寫(xiě)法,但是如果用styled-components的方式,那又該怎么樣繁仁?如下代碼所示

import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import styled from "styled-components"; // 引入styled-components

// 在Render函數(shù)外定義樣式組件
const CounterWrap = styled.div`
  text-align: center;
`

const SpanText = styled.span`
  padding: 0 15px;
`

const Button = styled.button`
  padding: 0 10px;
`

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0
    }
  }

  increment = () => this.setState({ count: this.state.count + 1 })
  decrement = () => this.setState({ count: this.state.count - 1 })

  render() {
    return (
      <Fragment>
        <CounterWrap>
          <Button onClick={this.decrement}>-</Button>
          <SpanText>{this.state.count}</SpanText>
          <Button onClick={this.increment}>+</Button>
        </CounterWrap>
      </Fragment>
    )
  }
}

const container = document.getElementById('root');

ReactDOM.render(<Counter />, container);

當(dāng)然你可以跟之前一樣,把樣式組件單獨(dú)的抽離出去的,然后通過(guò)export對(duì)外暴露出去的,當(dāng)需要使用時(shí),在另一文件內(nèi)通過(guò)import引入即可

對(duì)于樣式組件的命名:因?yàn)槭墙M件,所以約定俗成的首字母大寫(xiě),這是為了區(qū)分普通的html標(biāo)簽元素

小tip:在vs-code推薦插件:vscode-styled-components

下面來(lái)總結(jié)一些styled-components的一些特性

styled-components支持的特性

  • 支持嵌套,變量和繼承:可以使用類(lèi)似sass,less的語(yǔ)法嵌套,可以使用變量來(lái)設(shè)置不同的樣式,使用這些不同樣式時(shí)只需要給樣式組件傳遞一個(gè)參數(shù)就可以了的,在樣式化組件內(nèi)部可以通過(guò)props來(lái)接收外部的的參數(shù)值

  • 事件監(jiān)聽(tīng)綁定:對(duì)于自定義的樣式化組件可以進(jìn)行事件監(jiān)聽(tīng)的綁定,這正是解決類(lèi)class聲明的自定義組件,無(wú)法綁定事件監(jiān)聽(tīng)的痛點(diǎn),onEventType事件類(lèi)型只針對(duì)原生HTML標(biāo)簽才起作用,而樣式化組件正好彌補(bǔ)了這一點(diǎn)

  • 模塊化css:按需引入組件的代碼,避免了一些多余的代碼

  • 唯一類(lèi)名,沒(méi)有類(lèi)名錯(cuò)誤,重復(fù):styled-components生成的樣式生成唯一的類(lèi)名归园。永遠(yuǎn)不必?fù)?dān)心重復(fù)黄虱,重疊或拼寫(xiě)錯(cuò)誤

  • 更容易的刪除樣式,維護(hù)簡(jiǎn)單:編寫(xiě)的樣式都與特定組件相關(guān)聯(lián),如果組件未使用(工具可以檢測(cè)到)并被刪除,則所有樣式都將被刪除,保持功能性的單一,達(dá)到了高內(nèi)聚,低耦合的組件化特點(diǎn)

  • 動(dòng)態(tài)樣式:樣式組件內(nèi)可以接收參數(shù),很簡(jiǎn)單地調(diào)整和拓展組件的樣式庸诱,而不需要建立很多個(gè) class 類(lèi)來(lái)維護(hù)組件的樣式

總結(jié)

本文主要講解了React編寫(xiě)樣式的姿勢(shì),并不是什么高大上的內(nèi)容,比較基礎(chǔ)

通過(guò)styled-components第三方庫(kù)的的引入,編寫(xiě)樣式化組件,這個(gè)并不是必須的,視項(xiàng)目公司團(tuán)隊(duì)而定,不使用這個(gè),通過(guò)css-module編寫(xiě)React的樣式也是可以的

當(dāng)然若是使用了styled-components,便解決了一些問(wèn)題,例如,樣式覆蓋,命名等痛點(diǎn),以及解決了在類(lèi)聲明組件當(dāng)中,無(wú)法給自定義組件綁定事件的問(wèn)題

本文只是學(xué)習(xí)了styled-components的一些常用的知識(shí),至于更多styled-components詳細(xì)的使用:可以多查閱styled-components的官方文檔的

https://www.styled-components.com/

itclancoder二維碼.jpg

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捻浦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子桥爽,更是在濱河造成了極大的恐慌朱灿,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钠四,死亡現(xiàn)場(chǎng)離奇詭異篇亭,居然都是意外死亡瓣距,警方通過(guò)查閱死者的電腦和手機(jī)逢艘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)漾稀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了淋叶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)伪阶。 經(jīng)常有香客問(wèn)我煞檩,道長(zhǎng),這世上最難降的妖魔是什么栅贴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任斟湃,我火速辦了婚禮,結(jié)果婚禮上檐薯,老公的妹妹穿的比我還像新娘凝赛。我一直安慰自己,他們只是感情好坛缕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布墓猎。 她就那樣靜靜地躺著,像睡著了一般赚楚。 火紅的嫁衣襯著肌膚如雪毙沾。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天宠页,我揣著相機(jī)與錄音左胞,去河邊找鬼。 笑死举户,一個(gè)胖子當(dāng)著我的面吹牛烤宙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俭嘁,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躺枕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了兄淫?” 一聲冷哼從身側(cè)響起屯远,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蔓姚,失蹤者是張志新(化名)和其女友劉穎捕虽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體坡脐,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泄私,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌端。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捅暴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咧纠,到底是詐尸還是另有隱情蓬痒,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布漆羔,位于F島的核電站梧奢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏演痒。R本人自食惡果不足惜亲轨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸟顺。 院中可真熱鬧惦蚊,春花似錦、人聲如沸讯嫂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)欧芽。三九已至晕粪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渐裸,已是汗流浹背巫湘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昏鹃,地道東北人尚氛。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洞渤,于是被迫代替她去往敵國(guó)和親阅嘶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容