一. React中CSS的概述
1.组件化天下的CSS
- 前面说过,整个前端已经是组件化的天下:
- 而
CSS的设计就不是为组件化而生的,所以在目前组件化的框架中都在需要一种合适的CSS解决方案
- 而
- 在组件化中选择合适的
CSS解决方案应该符合以下条件:- 可以编写局部
css:css具备自己的局部作用域,不会随意污染其他组件内的元素 - 可以编写动态的
css:可以获取当前组件的一些状态,根据状态的变化生成不同的css样式 - 支持所有的
css特性:伪类、动画、媒体查询等 - 编写起来简洁方便、最好符合一贯的
css风格特点
- 可以编写局部
2.React中的CSS
- 事实上,
css一直是React的痛点,也是被很多开发者吐槽、诟病的一个点 - 在这一点上,
Vue做的要好于React:Vue通过在.vue文件中编写<style></style>标签来编写自己的样式- 通过是否添加
scoped属性来决定编写的样式是全局有效还是局部有效 - 通过
lang属性来设置你喜欢的less、sass等预处理器 - 通过内联样式风格的方式来根据最新状态设置和改变
css
Vue在CSS上虽然不能称之为完美,但是已经足够简洁、自然、方便了,至少统一的样式风格不会出现多个开发人员、多个项目采用不一样的样式风格- 相比而言,
React官方并没有给出在React中统一的样式风格:- 由此,从普通的
css,到css modules,再到css in js,有几十种不同的解决方案,上百个不同的库 - 大家一致在寻找最好的或者说最适合自己的
CSS方案,但是到目前为止也没有统一的方案
- 由此,从普通的
二. 内联样式CSS写法
内联样式是官方推荐的一种
css样式的写法:style接受一个采用小驼峰命名属性的js对象,,而不是CSS字符串- 并且可以引用
state中的状态来设置相关的样式
内联样式的优点:
- 1.内联样式, 样式之间不会有冲突
- 2.可以动态获取当前
state中的状态
内联样式的缺点:
- 写法上都需要使用驼峰标识
- 某些样式没有提示
- 大量的样式, 代码混乱
- 某些样式无法编写(比如伪类/伪元素)
所以官方依然是希望内联适合和普通的
css来结合编写
三. 普通CSS文件写法
- 普通的
css我们通常会编写到一个单独的文件,之后再进行引入 - 这样的编写方式和普通的网页开发中编写方式是一致的:
- 如果我们按照普通的网页标准去编写,那么也不会有太大的问题
- 但是组件化开发中我们总是希望组件是一个独立的模块,即便是样式也只是在自己内部生效,不会相互影响
- 但是普通的
css都属于全局的css,样式之间会相互影响
- 这种编写方式最大的问题是 样式之间会产生覆盖

四. CSS Module写法
css modules并不是React特有的解决方案,而是所有使用了类似于webpack配置的环境下都可以使用css module的- 如果在其他项目中使用它,那么我们需要自己来进行配置,比如配置
webpack.config.js中的modules: true等
- 如果在其他项目中使用它,那么我们需要自己来进行配置,比如配置
React的脚手架create-react-app已经内置了css modules的配置:.css/.less/.scss等样式文件都需要修改成.module.css/.module.less/.module.scss等- 之后就可以引用并且进行使用了
css modules确实解决了局部作用域的问题,也是很多人喜欢在React中使用的一种方案- 最终生成的类名的格式是:
文件名_类名_哈希值,如:Home_section_fxImn - 但是这种方案也有自己的缺陷:
- 引用的类名,不能使用连接符(
.xxx-xxx),在js中是不识别的 - 所有的
className都必须使用{module.className} 的形式来编写 - 不方便动态来修改某些样式,依然需要使用内联样式的方式
- 引用的类名,不能使用连接符(
- 如果你觉得上面的缺陷还算OK,那么你在开发中完全可以选择使用
css modules来编写,并且也是在React中很受欢迎的一种方式

五. react脚手架中使用less的方案
方案一:
- 通过
npm run eject命令暴露webpack文件,然后修改webpack配置,安装对应的loader如less-loader,css-loader,style-loader
- 通过
方案二:
craco(create-react-app-config,一个对create-react-app进行自定义配置的社区解决方案)ant design本身是用less编写样式的,也是用react,其文档中有提到如何在react中使用lessant design官网有对应的使用说明:https://ant.design/docs/react/use-with-create-react-app-cn#%E9%AB%98%E7%BA%A7%E9%85%8D%E7%BD%AE安装
craco并修改package.json里的scripts属性shellnpm i @craco/craco -D通过
craco命令来运行,会合并根目录下的craco.config.js配置文件到webpack的配置里json// package.json "scripts": { - "start": "react-scripts start" + "start": "craco start" - "build": "react-scripts build" + "build": "craco build" - "test": "react-scripts test" + "test": "craco test" }craco目前支持4.x的create-react-app版本,如果我们脚手架create-react-app使用的5.x,可以安装aplha版本更新:
2022-11-10
craco目前最新版本7.0.0开始支持5.x.x版本的react-scripts
craco作者对应的回答:https://github.com/dilanx/craco/issues/445加不加
-D,都不影响项目开发,但是按照规范来,最好加上-D(即开发阶段依赖)shellnpm i @craco/craco@alpha -D在项目根目录创建一个
craco.config.js用于修改默认配置js// craco.config.js module.exports = { // ... };引入
craco-less来帮助加载less样式和修改变量安装
craco-less- 如果有版本问题,导致安装失败,也可采取安装其对应的
alpha版本 - 按照规范来说,可以加
-D,如果忘记加-D,不需要重新安装 - 直接修改
package.json将dependencies中craco-less对应的代码,移动到devDependencies中也是可以的 - 这种东西对我们项目开发来说,不影响的,如果是用于第三方库开发,是需要注意的
shellnpm i craco-less -D npm i craco-less@alpha -D- 如果有版本问题,导致安装失败,也可采取安装其对应的
修改
craco.config.js文件如下jsconst CracoLessPlugin = require('craco-less'); module.exports = { plugins: [ { plugin: CracoLessPlugin, // 下面这些是针对ant design增加的一些配置,如果没用到ant design,可以不配置下面的选项 options: { lessLoaderOptions: { lessOptions: { modifyVars: { '@primary-color': '#1DA57A' }, javascriptEnabled: true, }, }, }, }, ], };
六. CSS in JS解决方案
1.认识CSS in JS
- 官方文档也有提到过
CSS in JS这种方案:- “
CSS-in-JS” 是指一种模式,其中CSS由js生成而不是在外部文件中定义 - 注意此功能并不是
React的一部分,而是由第三方库提供 React对样式如何定义并没有明确态度
- “
- 在传统的前端开发中,我们通常会将结构(
HTML)、样式(CSS)、逻辑(js)进行分离- 但是在前面的学习中,我们就提到过,
React的思想中认为逻辑本身和UI是无法分离的,所以才会有了JSX的语法 - 样式呢?样式也是属于
UI的一部分 - 事实上
CSS-in-JS的模式就是一种将样式(CSS)也写入到js中的方式,并且可以方便的使用js的状态 - 所以
React又被人称之为All in JS - 当然,这种开发的方式也受到了很多的批评:
Stop using CSS in JavaScript for web developmenthttps://hackernoon.com/stop-using-css-in-javascript-for-web-development-fa32fb873dcc
- 但是在前面的学习中,我们就提到过,
2.认识styled-components
批评声音虽然有,但是在我们看来很多优秀的
CSS-in-JS的库依然非常强大、方便:CSS-in-JS通过js来为CSS赋予一些能力,包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用、动态修改状态等等- 虽然
CSS预处理器也具备某些能力,但是获取动态状态依然是一个不好处理的点 - 所以,目前可以说
CSS-in-JS是React编写CSS最为受欢迎的一种解决方案
目前比较流行的**
CSS-in-JS的库**有哪些呢?styled-componentsemotionglamorous
目前可以说
styled-components依然是社区最流行的CSS-in-JS库,所以我们以styled-components的讲解为主安装
styled-components:shellnpm i styled-components
3.ES6标签模板字符串
ES6中增加了模板字符串的语法,这个对于很多人来说都会使用但是模板字符串还有另外一种用法:标签模板字符串(
Tagged TemplateLiterals)我们一起来看一个普通的
js的函数:正常情况下,我们都是通过
函数名()方式来进行调用的,其实函数还有另外一种调用方式:
如果我们在调用的时候插入其他的变量:
- 模板字符串被拆分了
- 第一个元素是数组,是被模块字符串拆分的字符串组合
- 后面的元素是一个个模块字符串传入的内容
在
styled components中,就是通过这种方式来解析模块字符串,最终生成我们想要的样式的
4.styled的基本使用
styled-components的本质是通过styled函数的调用,最终创建出一个组件:- 这个组件会被自动添加上一个唯一的
class styled-components会给该class添加相关的样式
- 这个组件会被自动添加上一个唯一的
另外,它支持类似于
CSS预处理器一样的样式嵌套:支持直接 子代选择器 或 后代选择器,并且直接编写样式
可以通过
&符号获取当前元素直接伪类选择器、伪元素等

5.props、attrs属性
props可以传递
·props可以被传递给styled组件- 获取
props需要通过${}传入一个插值函数,该函数会被自动调用,props会作为该函数的参数 - 这种方式可以有效的解决动态样式的问题
- 获取
添加
attrs属性,该属性可以设置props中某些属性的默认值,attrs属性本身也是一个函数,其返回值也是函数,可以形成链式调用attrs定义的属性,也会被合并到props中的
也可以这样写
`
6.styled高级特性
支持样式的继承
通过
styled函数传入对应的样式组件,可以实现样式的继承
styled设置主题

七. classnames库使用
1.vue中添加class
vue中添加class是一件非常简单的事情:传入一个对象:
vue<div class="static" v-bind:class="{ active: isActive, 'aaa': isAaa}"></div>传入一个数组:
vue<div :class="[active, aaa]"></div>对象和数组混合使用:
vue<div :class="[{ active: isActive }, aaa]"></div>
2.React中添加class
React在JSX给了我们开发者足够多的灵活性,你可以像编写js代码一样,通过一些逻辑来决定是否添加某些class:
这个时候我们可以借助于一个第三方的库:
classnamesjsnpm i classnames很明显,这是一个用于动态添加
classnames的一个库
