React中书写css代码
React本身就是一个支持组件化的框架,但是React并没有对css处理好组件化。相较于Vue,Vue这个一块就处理的很好,css放置在style标签中,而且可以设置scope作用域,防止样式覆盖,也可以设置css预处理器。
在组件化开发中我们需要书写局部的css,全局的css,动态的css(根据状态来设置css)。
React中书写css就没有那么的方便,下面介绍一些在React中css的书写方式。
内联样式
官方推荐的一种写法。
export default class componentName extends Component {
render() {
return (
<div>
<h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
<h2 className='title'>世界</h2>
</div>
);
}
}css中短横线链接的属性需要转为小驼峰的形式来书写,以对象的形式书写css样式,同时可以引入state中的属性来动态引入属性。
当然缺点很明显,如果需要书写大量的代码,那这种方式一定不方便,没有代码提示等。另外一些样式也不能书写,伪元素等选择器是不能书写的。
普通的css引入
我们将css单独写在一个文件中,在引入到文件中。
import React, { Component } from "react";
import './index.css'
export default class componentName extends Component {
render() {
return (
<div>
<h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
<h2 className='title'>世界</h2>
</div>
);
}
}但这样引入的css没有组件之间的作用域,是作用在全局的,属于全局css,会相互影响。所以适合写一些基本的全局样式。
css module 写法
该方法不是React自带的方法,只要在类似webpack配置打包环境下都可以使用。如果在其他项目中使用我们需要自己配置,配置webpack.config.js中的属性modules:true等。
React脚手架已经配置了css modules的配置。我们书写的.css/.less/.scss都需要修改为.module.css/.module.less/.module.scss。
引入方式,需要一个变量来接受,className需要以{style.className}形式来书写
import React, { Component } from "react";
import style from './index.module.css'
export default class componentName extends Component {
render() {
return (
<div>
<h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
<h2 className={style.title}>世界</h2>
</div>
);
}
}这样就避免了作用域问题,渲染出来的className如下:
当然缺陷也有,比如引入的类名不能是短横线连接,不方便修改属性。但这方法也是不错的css书写方式。
CSS in JS
通过js来增强React中css书写的一种方式。当然我们学些这个方式前先了解下ES6的一种语法,ES6标签模板字符串
我们使用该方法需要引入第三方库,这里推荐以下几个库:
- styled-components
- emotion
- glamorous
我们以styled-components这个库来演示,这个库在社区中是很流行的。
安装方式:
//npm方式
npm install styled-components -S
//yarn方式
yarn add styled-components该库本质上是调用函数来创建一个组件,组件会添加不会重复的class。
该方式支持css预处理器的嵌套写法,支持css的各类写法。
基本用法:
import styled from "styled-components";//创建一个组件
const TitleWrapper = styled.div`
color: yellow;
.title {
background-color: tomato;
&::after {
content: "---aaa";
}
}
`;这个函数中根元素为div,其中的样式只作用于该组件中
export default class CssInJS extends Component {
state = {color:'pink'}
render() {
return (
<div>
<TitleWrapper>
我是谁
<h3 className="title">hahah</h3>
</TitleWrapper>
</div>
);
}
}
渲染结果:


props,attr属性
props可以穿透,直接作用在元素上
const InputWrapper = styled.input`
background-color: red;
`;
export default class CssInJS extends Component {
state = {color:'pink'}
render() {
return (
<div>
{/* 属性是可以穿透的,直接应用到标签上 */}
<InputWrapper type="password"></InputWrapper>
</div>
);
}
}渲染结果:

另外获取props需要通过${}形式获取,其中定义一个函数,props会作为函数的参数。
const InputWrapper = styled.input`
background-color: red;
padding: ${(props) => props.padding};
`;
export default class CssInJS extends Component {
state = { color: "pink" };
render() {
return (
<div>
<InputWrapper type="text" padding="20px"></InputWrapper>
</div>
);
}
}

attr属性,为元素设置一些默认属性
const Input2Wrapper = styled.input.attrs({
placeholder: "zhangsan",
bColor: "red",//这种不存在的属性不能添加
'data-day':111
})`
background-color: #f2f2f2;
color: ${(props) => props.color};
`;
export default class CssInJS extends Component {
state = { color: "pink" };
render() {
return (
<div>
<Input2Wrapper color={this.state.color} />
</div>
);
}
}渲染效果:

高级特性
支持样式继承
我们可以将另一个组件传入函数中来实现样式的继承
const SuperButton = styled.button`
padding: 8px 30px;
border-radius: 5px;
`;
const MyButton = styled(SuperButton)`
background-color: red;
color: #bfa;
`;
export default class CssInJS extends Component {
render() {
return (
<div>
<MyButton>按钮</MyButton>
</div>
);
}
}渲染效果:


主题设置
import CIJ from "./cssInJS";
import { ThemeProvider } from "styled-components";
function App() {
return (
<div className="App">
你好
<ThemeProvider theme={{color:'#bcf', fontSize:'30px'}}>
<CIJ></CIJ>
</ThemeProvider>
</div>
);
}
export default App;后代元素中获取theme中的属性
const TitleWrapper = styled.div`
color: ${(props) => props.theme.color};
font-size: ${(props) => props.theme.fontSize};
.title {
background-color: tomato;
&::after {
content: "---aaa";
}
}
`;动态添加className
在项目中我们需要为组件动态的添加一些css类名,这在react中只能自己实现。
React没有为我们提供像Vue中的一些模板语法(比如一些指令v-bind等),我们可以借助一个第三方库classnames来简化我们的工作量。
//npm
npm install classnames -S
//yarn
yarn add classnamesimport React, { Component } from 'react'
import classNames from 'classnames';
export default class App extends Component {
constructor(props){
super(props);
this.state = {
isActive:true,
info:'info'
}
}
render() {
return (
<div>
<h2 className={'title ' + (this.state.isActive?'active':'')}>你好</h2>
<h2 className={classNames('foo', 'active')}>世界</h2>
<h2 className={classNames({'title':this.state.isActive}, 'foo')}>000</h2>
<h2 className={classNames({'title':this.state.isActive}, 'foo')}>111</h2>
<h2 className={classNames({'title':this.state.isActive}, 'foo', this.state.info)}>222</h2>
</div>
)
}
}渲染结果:

Comment here is closed