# CSS 在 React 和 Vue 中的应用
# Vue 中使用 CSS 方案
# Vue 自带的Scoped CSS
加上 scoped 属性的style会自动添加一个唯一的属性 。比如 data-v-0767f757 为组件内 CSS 指定作用域,编译的时候 .isShow 会被编译成类似 .isShow[data-v-0767f757]
<style lang="css" scoped>
.isShow{
background:red;
}
</style>
2
3
4
5
缺点:.errShow[data-v-0467f817]并不能保证是唯一的,另外在性能上也不是很好
# CSS modules
需要同时使用 webpack 的 Vue Loader
CSS Modules 是一个流行的,用于模块化和组合 CSS 的系统。vue-loader
提供了与 CSS Modules 的一流集成,可以作为模拟 scoped CSS 的替代方案。
// webpack.config.js
{
module: {
rules: [
// ... 其它规则省略
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// 开启 CSS Modules
modules: true,
// 自定义生成的类名
localIdentName: '[local]_[hash:base64:8]'
}
}
]
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
构建步骤中对CSS类名选择器限定作用域的一种方式(通过hash实现类似于命名空间的方法)。类名是动态生成的,唯一的,并准确对应到源文件中的各个类的样式
<template>
<p :class="$style.red">
This should be red
</p>
</template>
<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
用法
- 在style标签中添加module属性,表示打开CSS-loader的模块模式。
- 在模板中使用动态类绑定:class,并在类名前面加上'$style.'。
- 如果类名包含中划线,则使用中括号语法$style['header-tit'] 也可以使用数组或对象语法。
# React 中使用CSS 方案
# CSS module
CSS Modules 通过webpack配置引入项目,不依赖于任何框架,只要使用webpack配置后就可以用于React/Vue/Angular/jQuery 项目中.
- 在webpack.config.js的module中添加如下配置:
module.exports = {
entry: __dirname + '/index.js',
output: {
publicPath: '/',
filename: './bundle.js'
},
module: {
rules:[
{
test:/.css$/,
use:[
{loader:'style-loader'},
{loader:'css-loader',
option:{modules:true,localIdentName:'[path][name]__[local]-[hase:base64:5]'}
]
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上面代码中,关键的是在css-loader
的option里配置option:{modules:true}
,表示打开 CSS Modules 功能。
/* components/submit-button.js */
import React, { Component } from 'react';
import classNames from 'classnames';
// 重点
import styles from './submit-button.css';
export default class SubmitButton extends Component {
render () {
let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';
let className = classNames({
[`${styles.base}`]: true,
[`${styles.inProgress}`]: this.props.store.submissionInProgress,
[`${styles.error}`]: this.props.store.errorOccurred,
[`${styles.disabled}`]: this.props.form.valid,
});
return <button className={className}>{text}</button>;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
详细查看:https://github.com/jd-smart-fe/shared/issues/11
# CSS-in-JS
以 styled components 方案为例
安装
npm install --save styled-components
使用
import styled from 'styled-components';
export default class SubmitButton extends Component {
// 给标签加样式
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// 给组件加样式,覆盖原来的部分样式
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
render(){
return (
<div>
<Button>Normal Button</Button>
<TomatoButton>Tomato Button</TomatoButton>
</div>
)};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Atomic CSS 原子化 CSS
原子 CSS 就像是实用工具优先(utility-first)CSS 的一个极端版本: 所有 CSS 类都有一个唯一的 CSS 规则。
/* 原子 CSS */
.bw-2x {
border-width: 2px;
}
.bss {
border-style: solid;
}
.sans {
font-style: sans-serif;
}
.p-1x {
padding: 10px;
}
/* 不是原子 CSS 因为这个类包含了两个规则 */
.p-1x-sans {
padding: 10px;
font-style: sans-serif;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Tailwind 使用的方法是非常便捷的,并且解决了上述一些问题。
以 Tailwindcss 为例它通过 Utility-First 的理念来解决 CSS 的一些缺点,通过抽象出一组类名 -> 原子功能的集合,来避免你为每个 div 都写一个专有的 class,然后整个网站重复写很多重复的样式。
它提供了一些公用的命名约定。通过一个配置文件,你可以为你的网站生成一套专属的实用工具 CSS
// tailwind.config.js
module.exports = {
theme: {
screens: {
'sm': '640px',
// => @media (min-width: 640px) { ... }
'md': '768px',
// => @media (min-width: 768px) { ... }
'lg': '1024px',
// => @media (min-width: 1024px) { ... }
'xl': '1280px',
// => @media (min-width: 1280px) { ... }
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18