# 一、React 中的 CSS
# 1、CSS 概述
在当前前端组件化开发的时代,一个合适的 CSS 方案应该符合以下条件:
局部的、动态的、简洁的、支持度高的……
# 2、内联样式
在 react 基础中就已经提到了 style={{}}
语法
class Demo extends React.Component {
constructor() {
super()
this.state = {
imageSize: 200
}
}
render() {
const { imageSize } = this.state
return (
<div>
{/* 直接使用 */}
<p style={{ color: 'red', fontSize: '30px' }}>
优于别人,并不高贵,真正的高贵应该是优于过去的自己。
</p>
{/* 使用变量 */}
<img style={{ width: imageSize, height: imageSize }} />
</div>
)
}
}
# 3、CSS Modules
这种方式就不做过多介绍了,缺点是这些 css 默认是全局的。
import '@/css/common.css'
为了解决 react 中的 css 全局问题,可以采用:
解决方案:CSS Modules🍗
CSS Modules 提供各种插件 (opens new window),支持不同的构建工具。
常见的是 Webpack 的 css-loader 插件,因为它对 CSS Modules 的支持最好。
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'css-loader',
options: {
modules: true // 开启 CSS Modules
}
}
]
}
}
当然,在 react 脚手架 (opens new window)中已经内置了 CSS Modules 的配置,我们只需要将样式文件名改为 .module.css、.module.less、.module.scss 等即可
提示
react 脚手架中的 CSS Modules 方案中,css 类名是不能使用连接符的(例如:.home-nav
)
import common from './Common.module.css' // Import css modules stylesheet as styles
class Demo extends Component {
render() {
return <button className={common.error}>错误信息</button>
// 会被解析为( 组件名_类名_hash值)
// return <button className="Common_error_ax7yz">错误信息</button>
}
}
# 二、CSS-in-JS ✨
# 1、简介
“CSS-in-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义。
此功能并不是 React 的一部分,而是由第三方库提供。
目前比较流行的 CSS-in-JS 库有:styled-components (opens new window)、emotion (opens new window)、glamorous (opens new window)
# 2、styled-components 库
常见的 react 组件库 Material UI (opens new window) 就采用了 styled-components
js 拓展:🌹 标签模板字符串
const name = 'lencamo'
const age = 22
function foo(...args) {
console.log(args) // [["my name is ", ", age is ", ""], "lencamo", 22]
}
foo`my name is ${name}, age is ${age}`
# 3、基本使用
- 编写全局 css 变量
通过编写 variables 文件直接在 css 组件中引入数据
// variables.js
export const primaryColor = '#ff8800'
export const secondColor = '#ff77788'
export const smallSize = '12px'
export const middleSize = '14px'
export const largeSize = '18px'
- 编写 css 组件
// style.js
import styled from 'styled-components'
import * as vars from '@/style/variables.js'
export const DemoWrapper = styled.div.attrs((props) => ({
// 直接返回对象
rColor: props.color || '#292c34' // 设置默认值
}))`
.section {
border: 1px solid red;
.title {
font-size: ${(props) => props.size}px;
color: ${(props) => props.rColor};
&:hover {
background-color: purple;
}
}
.content {
font-size: ${vars.largeSize}px;
color: ${vars.secondColor};
}
}
.footer {
border: 1px solid orange;
}
`
- 使用 css 组件
可以在使用 props 向 css 组件传递数据
import { DemoWrapper } from '@/css/style.js'
class Demo extends PureComponent {
constructor() {
super()
this.state = {
size: 30,
color: 'green'
}
}
render() {
const { size, color } = this.state
return (
// DemoWrapper本身是一个组件
<DemoWrapper size={size} color={color}>
<div className="section">
<h2 className="title">我是标题</h2>
<p className="content">我是内容,哈哈哈</p>
</div>
<div className="footer">
<p>免责声明</p>
<p>版权声明</p>
</div>
</DemoWrapper>
)
}
}
其他高级特性
- 支持样式的继承
- 支持设置主题 ThemeProvider
- ……
# 三、动态添加 class
# 知识回顾
- vue 中添加 class
<!-- 数组、对象 -->
<div
class="static"
:class="['baseCss', activeClass, hasError ? 'text-danger' : '', { 'text-danger': hasError }]"
></div>
- react 中添加 class
// 字符串、数组
<div
className={`one two ${isShow ? 'avatar' : ''}`}
className={['one', 'two', isShow ? 'avatar' : ''].join(' ')}
></div>
# 1、classnames 库
classnames 库 (opens new window)的使用和 vue 中的添加 class 方式类似
import classname from 'classnames'
class Demo extends React.PureComponent {
render() {
return <div className={classname(['one', 'two', { avatar: isShow }])}></div>
}
}
← react组件(下) 过渡与动画 →