React腳手架(3)組件的樣式和styled-components

組件的樣式

一、簡單使用

我們可以爲每個組件單獨創建一個css樣式文件,然後在js文件中,直接導入使用:

// header-nav.js
...
import './header-nav.css'
...

但是這種方式導入的樣式會作用於全局。如果要讓當前樣式只生效於當前組件,可以在選擇器上加以限制。比如在聲明組件時爲當前組件的根元素添加一個唯一的id或類名。然後在樣式列表中加上這個選擇器標識即可:

// header-nav.js
...
class HeaderNav extends React.Component {
	render() {
		return (
			<div className="header-nav">
				<div></div>
				<div></div>
			</div>
		);
	}
}
...
/* header-nav.css */
.header-nav div {
	// style list
}

二、React的styled-components

React 是組件結構,建議把 HTML、CSS、JavaScript 寫在一起,以此形成組件低耦合、高複用的特點。所以在React中,組件的結構、樣式和邏輯可能都要使用JS(TS)完成。

React中,用 JS 編寫組件的樣式,要用CSS in JS(文末有具體介紹的文檔鏈接),CSS in JS的庫有很多中,本文介紹styled-components(較爲主流的CSS in JS庫)

  1. 安裝styled-components
npm install --save styled-components

我安裝完之後項目無法啓動了,報的錯是,是因爲安裝了新的依賴

react-scripts: command not found

重新安裝了一下node_modules文件夾就好了

npm i
  1. 全局的樣式
    styled-componentsV4之前的版本使用injectGlobal創建全局的樣式。V4將injectGlobal移除了,要創建全局的樣式需要使用createGlobalStyle,並在組件中以子組件的形式調用。

全局的樣式封裝

// src/style.js
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    color: #333;
    font-size: 16px;
    padding: 30px;
  }
`;

export default GlobalStyle

全局的樣式調用

// App.js
...
import GlobalStyle from './style'
...
class App extends Component {
  render() {
    return (
      <div className="App">
        <GlobalStyle />
      </div>
    );
  }
}
...

注:一般情況下我們都利用createGlobalStyle做整個項目的樣式重置(reset)

  1. 樣式化的組件
    通過上面的全局樣式示範,我們能看到,styled-components刪除了組件和樣式之間的映射。當定義樣式時實際上是在創建一個普通的React組件,只不過其中附加了樣式。

樣式化組件的封裝

// src/components/header-nav/style.js
import styled from 'styled-components'

export const Title = styled.div`
 font-size: 1.5rem;
 color: palevioletred;
`;

樣式化組件的調用

// src/components/header-nav/header-nav.js
import React from 'react'
import { Title } from './style'

class HeaderNav extends React.Component{
	render() {
		return (
			<div className="header-nav">
				<div className="box1">你凝視着深淵,深淵也凝視着你。</div>
				<Title>
					<div className="box2">我的眼睛注視着萬物。</div>
				</Title>
			</div>
		);
	}
}
export default HeaderNav

在瀏覽器中的具體呈現效果:

經過解析的DOM結構:
elements
注:

  • 在封裝樣式時,聲明瞭Title組件,是一個div標籤(styled.div,如果聲明時寫了styled.h1,那Title就是h1標籤);
  • Title可以被複用(樣式化的組件一旦被聲明,只要導入,就可在任意位置複用);
  • Title不僅被解析成了div,還自動被添加了一個選擇器,這個選擇器是styled-components自動添加的,方便代碼複用;
  • 樣式化的組件調用時,樣式生效於被調用的局部,非全局。
  1. 樣式化組件的嵌套

封裝

// src/components/header-nav/style.js
import styled from 'styled-components'

export const Title = styled.div`
 font-size: 1.5rem;
 color: palevioletred;
`;

export const Wrapper = styled.div`
 font-weight: bolder;
`;

調用

// src/components/header-nav/header-nav.js
import React from 'react'
import { Wrapper,Title } from './style'

class HeaderNav extends React.Component{
	render() {
		return (
			<Wrapper>
				<Title>
					只有能被明日的我們銘記,今天才有意義。
				</Title>
			</Wrapper>
		);
	}
}
export default HeaderNav

注:樣式化組件嵌套時,子組件會繼承父組件的樣式。

  1. 樣式化組件的參數

一個樣式化組件被封裝,有些樣式可能需要在被調用的時候根據代碼上下文才能確定,所以styled-components允許在封裝樣式組建時傳參

封裝

// src/components/header-nav/style.js
import styled from 'styled-components'

export const Title = styled.div`
 font-size: 1.5rem;
 color: ${props => props.type == 'success' ? 'green' :
 props.type == 'warning' ? 'orange' : '#444'};
`;

export const Wrapper = styled.div`
 font-weight: bolder;
`;

調用

// src/components/header-nav/header-nav.js
import React from 'react'
import { Wrapper,Title } from './style'

class HeaderNav extends React.Component{
	render() {
		return (
			<Wrapper>
				<Title type="warning">只有能被明日的我們銘記,今天才有意義。</Title>
				<Title type="success">生命無法承載意義,但你的死亡卻可以。</Title>
			</Wrapper>
		);
	}
}
export default HeaderNav
  1. 樣式化組件中的子選擇器

封裝

// src/components/header-nav/style.js
...
// 封裝Wrapper組件的同時封裝其子選擇器.box的樣式,如果在Wrapp組件中,某個元素的類名爲box,就會自動生效
export const Wrapper = styled.div`
	font-weight: bolder;
	.box {
		background: #eee;
		padding: 20px;
	}
`;
...

這些示例都是基本操作,實際上styled-components提供了很多樣式編寫方式,具體請查看文檔。

參考文檔:
阮一峯,CSS in JS簡介
styled-components官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章