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中,编写组件的样式,要用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

在浏览器中的具体呈现效果:
React脚手架(3)组件的样式和styled-components_第1张图片
经过解析的DOM结构:
React脚手架(3)组件的样式和styled-components_第2张图片
注:

  • 在封装样式时,声明了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官方文档

你可能感兴趣的:(前端开发,框架)