React中的CSS
在React开发中, 样式风格是一个被很多人吐槽的点, 因为其官方没有统一的样式风格,故从普通的css, 再到css in js, N多的解决方法, N多的库. 在开始到现在React中也没有一套统一的方案被广大用户所接受.
内联样式
-
内联样式是官方推荐与普通样式进行结合编写的一种写法
- 将一个用小驼峰命名属性的JavaScript对象传给style
jsclass App extends Component { constructor(){ super() this.state = { isShowBg: false } } render() { const { isShowBg } = this.state return ( <div> <h2 style={{color: "#f00", fontSize: '16px'}}>内联样式</h2> <h2 style={{fontSize: '16px', background: isShowBg ? '#f00' : ''}}>内联样式 -- 根据state的值来判定是否显示背景色</h2> </div> ) } }
-
优点
- 样式与样式之前不会产生冲突
- 可以动态根据state中的值来设定对应的样式
-
缺点
- 像字体大小这样的font-size必须使用小驼峰形式编写fontSize
- 编写样式缺少提示, 容易出错
- 样式代码会占据大量空间, 不易阅读
- 一些特定的样式无法编写, 例如伪类, 伪元素等
普通的css
普通的css与通常的开发一致, 通常编写到一个单独的文件中, 但是若用到组件化开发中, 我们希望组件的作用效果只在内部, 不会互相影响, 但是普通的css属于全局样式, 一处编写多处受用,
故不易修改, 且出现问题修改后可能会影响别的组件
css modules
- css modules是在webpack配置下使用的
- React中已内置css modules的配置, 只需要将样式文件后缀改为 .module.xxx 例如.css/.less等修改为对应的.module.css/.module.less, 然后引用即可使用
css
/* 定义APP css文件 */
.title {
color: blue;
font-size: 24px;
}
.content {
color: aqua;
font-size: 24px;
}
css
/* 定义Home.module.css文件 */
.title {
color: #f00;
font-size: 12px;
}
js
// 在App组件中引入样式APP.css, 及组件
import './App.css'
export class Home extends Component {
render() {
return (
<div>
<div className='title'>APP title</div>
<div className='title'>APP content</div>
<Home />
</div>
)
}}
// 在home组件中应用home.module.css文件, 并使用
import homeStyle from './Home.module.css'
export class Home extends Component {
render() {
return (
<div>
<div className={homeStyle.title}>Home title</div>
<div className='content'>Home content</div>
</div>
)
}
}
页面运行后即可看见, 普通css设置的样式全局都发生了变化, 而css modukes设置的样式只是影响了对应的组件
- css modules的缺点
- 使用的类名中不能编写类似于(.home-title)的这种类名
- 所使用的所有类名必须以(style.className)来编写
- 不方便动态修改样式
css in js
- 首先使用CSS in Js的第一步是需要了解标签模板
- (文章的第七点有讲: es6.ruanyifeng.com/#docs/strin...)
- 以文中描述来说就是 标签模板其实不是模板,而是函数调用的一种特殊形式。"标签"指的就是函数,紧跟在后面的模板字符串就是它的参数。 但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
js
// 首先安装依赖styled-components
// 定义style.js文件
import styled from "styled-components"
// 定义一个最外层的包裹元素
// 安装插件scode-styled-components 来实现代码提示编写
export const HomeWrapper = style.div`
.title {
color: #f00,
font-szie: 18px
}
`
// 设置默认值
// 箭头函数的加小括号的函数体返回对象字面量表达式
// .attrs(
// props =>
// {
// return {
// tSize: props.size || '20px'
// }
// })
export const HomeWrapper = styled.div.attrs(props => ({ tSize: props.size || '20px' }))`
.title {
font-weight: bold;
font-size: ${props => props.tSize};
color: ${props => props.color}
}
`
jsx
// 在文件中引入HomeWrapper
import { HomeWrapper } from './style.js'
export class Home extends Component {
render() {
return (
<HomeWrapper>
<div className='title'>Home title</div>
</HomeWrapper>
)
}
}
运行以上代码则可以看见Home title的对应样式,及内容已经被修改
classnames
classnames 是一个简单的 JavaScript 工具包用来有条件的将不同的 classNames 联合在一起
js
// 示例代码
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'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
// 1. 安装依赖库classnames
// 2. 在页面对应的位置编写样式即可
<div className={classNames('aaa', {bbb: showBbb , ccc: showCcc})}>className</div>