写在前面
食用此文档需要你至少具备
- 基础的css使用
- 基础的JavaScript使用
- 基础的react的使用
在React还未出现的时候, 网页开发有一个原则叫做关注点分离
(正交原则
)
关注点分离
首先看一下百度百科的解释
关注点分离(Separation of concerns,SOC)是对只与“特定概念、目标”(关注点)相关联的软件组成部分进行“标识、封装和操纵”的能力,即标识、封装和操纵关注点的能力。是处理复杂性的一个原则。由于关注点混杂在一起会导致复杂性大大增加,所以能够把不同的关注点分离开来,分别处理就是处理复杂性的一个原则,一种方法。
通俗易懂的说就是, HTML, css, JavaScript 分离, 不要混到一起用, 不要写 行内样式
和 行内脚本
, 比如下面的代码就很糟糕
Hello World
正确的做法是分为三个部分, 分别写html/css/javaScript
Hello World
.title {
color: red;
font-size: 46px;
}
const titleDom = document.querySelector('.title');
titleDom.addEventListener('click', sayHi);
function sayHi() {
alert('Hi');
}
React 的出现
React
出现以后, 这个原则不再适用了。 因为React
是组件结构, 强制要求把 HTML、CSS、JavaScript 写在一起。
上面的例子使用 React 改写如下
const style = {
'color': 'red',
'fontSize': '46px'
};
const clickHandler = () => alert('hi');
ReactDOM.render(
Hello, world!
,
document.getElementById('example')
);
上面代码在一个文件里面,封装了结构、样式和逻辑,完全违背了"关注点分离"的原则。
但是,这有利于组件的隔离。每个组件包含了所有需要用到的代码,不依赖外部,组件之间没有耦合,很方便复用。所以,随着 React 的走红和组件模式深入人心,这种关注点混合
的新写法逐渐成为主流。
css in js
由于React的出现, 使得关注点混合
的新写法逐渐成为主流, 但由于React对css的封装非常弱, 导致了一系列第三方库, 用来加强React
的 css操作, 也就是说css in js 技术仅仅适用于关注点混合的结构
由于只要是加强JavaScript 对 css 的操作就可以称为css in js
, 因此css in js
并没有统一的实现方式, 如果你要挑选css in js
类库, 可以在MicheleBertoli/css-in-js中找你喜欢的库, 这里收集了大量使用较多的css in js
库
下面介绍一款css in js
类库的使用
Aphrodite
目前排名第一的是 Aphrodite 这个类库,这里我写了一个Aphrodite的在线模板, 可以直接在上面练习
先来看一下基础用法
import React from "react";
import ReactDOM from "react-dom";
import { StyleSheet, css } from "aphrodite";
// 创建样式
const styles = StyleSheet.create({
red: { color: "red" }
});
ReactDOM.render(
// 载入样式
Hello aphrodite!
,
document.getElementById("root")
);
在线示例
既然是用JS来控制CSS, 就可以用条件判断来容易的控制样式
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { StyleSheet, css } from "aphrodite";
// 创建样式
const styles = StyleSheet.create({
red: { color: "red" },
green: { color: 'green' }
});
class App extends Component {
constructor(props) {
super(props);
this.state = { isGreen: false };
this.handleClick = this.handleClick.bind(this);
}
/**
* 点击事件, 用来切换红色与绿色
*/
handleClick() {
this.setState({
isGreen: !this.state.isGreen,
});
}
/**
* 获取组件样式表
*/
getClassName() {
const { isGreen } = this.state;
const titleClassName = css(isGreen ? styles.green : styles.red);
return { titleClassName };
}
render() {
const { handleClick } = this;
const { titleClassName } = this.getClassName();
return (
Hello aphrodite!
);
}
}
ReactDOM.render( , document.getElementById("root"));
在线示例
Aphrodite默认所有的样式都增加了 !important 如果不想要这个特性, 可以引入aphrodite/no-important
import { StyleSheet, css } from 'aphrodite/no-important';
除了以上基础用法, Aphrodite还提供了minify
函数, 用来压缩css
import { StyleSheet, minify } from 'aphrodite';
minify(true);
Aphrodite还可以在非react的环境下使用, 但不推荐这样做, 这里不做示例了
另外使用Aphrodite还要注意, 在获取元素属性时, 需要做一下延时, 因为Aphrodite不能确保设置的元素样式会立即生效
Style injection and buffering
Aphrodite will automatically attempt to create a将类名暴露出去, 并暴露一个方法
css
, 作用就是自动拼接className
, 并去重
使用
css
解析出的className
以上 ~
参考文章:
- github
- 阮一峰的网络日志