《深入react技术栈》之样式处理

基本样式设置

像素单位处理

对于样式中的与大小相关的值,react进行了优化处理,我们直接使用数字即可,不用写px单位。

let style = {
	width: 18
}
复制代码

classname库

在我们不使用库之前,需要自己动态拼接classname的字符串。源文件也非常简单,其下载量也说明其使用频率比较高,参考源码:链接

render(){
	const {isPressed, isActive} = this.state;
	let btnClass = 'btn';
  if(isPressed){btnClass +='pressed' };
  if(isActive){btnClass +='active' };
 
} 

// 有了之后 
import classNames from 'classNames';
render(){
	const {isPressed, isActive} = this.state;
	let btnClass = {
  	'btn':true,
    'pressed':isPressed,
    'isActive':isActive
  }
} 

复制代码

基本api如下:

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// 数组的支持
var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'
复制代码

css modules

可以采取的方案

css模块化的方案主要有两种,分别为行内样式以及结合js收集依赖进行管理的css modules。

而行内样式具有明显的几个痛点是不能解决的,比如伪元素、动画、媒体查询等,所以实际开发中,我们只有一些简单的样式处理才会使用行内样式,整体的样式方案并不会使用行内样式。

结合js收集css依赖,可以很方便的进行管理,而且webpack内置的css-loader可以很好地将样式以及js拆分出来。

面临的主要问题

全局样式污染

我们默认的样式选择器是基于全局的,会造成全局样式污染,为了覆盖样式,我们就需要使用!important这样的语句来覆盖。当然我们也可以使用组件内样式,但这样会导致外部无法重写样式,损失了灵活性。

命令混乱

也是由于全局命名的规则,由于各个成员的命名规则不统一,导致样式名称混乱。

依赖管理不彻底

大多数开发者对于依赖管理不够彻底,只是关心全局样式是否可用,不可用则直接重写或者覆盖。

无法共享变量

不同的样式文件中,无法共享一些变量。

代码压缩不彻底

使用css-module

开启模块化

在webpack.config.js中设置css?modules&localIdentName=[name]_[local]-[hash-base64-5].加上之后,我们在引入样式时就可以实现样式的重命名,也可以方便的引入和控制某部分样式。比如:

// button.css
.normal{}
.disabled{}
复制代码
import styles from './button.css';

render(){
	return <button className={styles.normal}/>
}

// 最终生成的css名称 ,button-normal-abc456
复制代码

通过这样的模块化,解决的问题:

  • 样式名冲突或者样式名的全局污染
  • 方便自定义样式名规则,可以简化样式名
  • 只需要关心js,引入了js组件便引入了js以及样式
  • 不需要学习额外的css规则

默认局部样式

在上面开启模块化之后,默认是局部样式,也就是加了:local的,如果你希望定义的样式是全局样式,你需要手动的加:global

组合样式 compose(不建议)

你可以使用compose来组合也就是复用样式。当然如果你使用的是其他样式预处理器,其本身具有很灵活的各种样式处理规则,可以忽略这点,另外一半样式预处理器也没有这条语法,请不要使用。

// button.css
.base{}
.active{
	compose:base;
  
}
复制代码

样式命名规则基于BEM

结合react

  • 如果你不想每次都加styles.,可以使用react-css-modules,它使用高级组件的方式避免重复输入styles
  • 使用模块化时,如果你想使用全局的这个样式,可以不用样式里加,直接在使用的时候加global-css即可,如果是局部样式,使用local-module.
  • react使用className的方式与传统方式的区别是,直接操作样式还是间接通过操作classname来操作样式。实际上,在资深的css开发者都会认为,为了样式更好的维护,我们是建议直接操作样式的,而不建议在js里拼接维护较多的样式代码。

小结

本文主要想提醒给大家的几个点:

  • 与大小有关系的样式属性不用加单位
  • 更建议直接通过classname去实现操作样式,通过对象的方式去配置,而不是自己拼接或者使用原始的classlist去操作
  • 如果你的项目存在较多的样式污染或者管理样式依赖的问题,那么建议你可以看下css module,也许能解决你的问题,使用也只是配置的问题,不需要额外的其他学习

猜你喜欢

转载自juejin.im/post/5c96e6bcf265da612a7aa276
今日推荐