react中通过jsx的语法形式,将html标签和js语法分割在一起,而css的编写形式,没有明确的指定编写形式,目前就有很多不同办法,每个形式各有其优缺点,咱们一起来看看罕用的定义形式有哪些。
最根底也是最简略的形式就是如html当中编写款式一样,间接内联应用,区别在于jsx中内联应用款式须要用小驼峰命名,不可应用短横线 -,jsx中编写js的表达式须要应用 {},而定义的款式是以对象的模式存在,也是通过{},所以看起来style标签外面应用了两个大括号{}
return(<div style={{color: 'blue'}}> hello react</div>)
这样的形式长处是代码不会抵触,定义的代码都作用于以后元素,而且如果须要动静的获取state的值来设置款式也能够做到。毛病也很显著,当如果款式十分多的时候,即便把款式整体提炼进去,作为一个变量赋值给style,但依然还是和业务逻辑混淆在一起,并且无奈编写伪类等一些语法。
第二种形式可能将css代码与业务逻辑代码拆散开来,在jsx的标签中定义className属性,自定义css的款式文件,再通过import引入css/scss/less等款式文件,就是应用的css的原生编写形式,定义伪类以及其它的高级选择器编写形式都能够反对。
return(<div className="title"> hello react</div>)// 定义在独自的款式文件.title { color: 'blue'}
这样能够让代码比拟清晰明了,css款式和jsx文件分来到。
当须要应用多个className,或者通过状态来变更className时,能够通过+来进行字符串拼接,或者应用数组,再通过toString()转成字符串
const isActive = true<h2 className="active foo bar">我是题目1</h2> // active foo bar <h2 className={"foo", (isActive ? "active" : "") }>我是题目2</h2> // active<h2 className={"foo" + (isActive ? " active" : "") }>我是题目3</h2> // foo, active<h2 className={["foo",(isActive ? "active" : "")]}>我是题目4</h2> // foo, active<h2 className={["foo",(isActive ? "active" : "")].join(" ")}>我是题目5</h2> // foo avtive
为了简便应用,能够间接应用 classnames 这个库来动静的应用类名,classnames默认裸露了一个函数,传入参数的参数能够为字符串、对象和数组,传入null/undefined/boolean值也不会显示在页面上
import classNames from 'classnames'const isShow = falseconst list = ['foo', 'bar']<h2 className={classNames({"active": isActive}, "foo")}>我是题目6</h2> // active foo<h2 className={classNames({"active": isActive, "bar": isShow })}>我是题目7</h2> // active <h2 className={classNames({"active": isActive}, list)}>我是题目8</h2> // active foo bar<h2 className={classNames(null, undefined, 0, 10, '0', true, false)}>我是题目8</h2> // 10 0
但react开发的页面都叫做单页面利用,整个我的项目只有一个页面,款式在a组件援用,b组件即便没有援用,定义了同名的类名,也会有款式,这样导致如果c组件和d组件都定义了className属性,别离引入了css款式定义字体色彩,但最终两者呈现出的字体色彩为后引入的css文件里的字体色彩,即同名的款式会被笼罩掉。
为了解决这一问题,咱们就须要在跟标签处再定义一个className,来包裹以后组件的所有标签,这样css款式的层级就比拟多,并且还可能因为选择器优先级的问题(在外层定义了id选择器),而产生款式抵触,同时它不反对获取state属性动静设置款式。
return(<div className="homeComponent"> <div className="title">hello react</div></div>)
此时就产生了第三种编写形式,css的模块化,这样的形式能够辨别各个组件的款式,不会互相笼罩,而且还能定义伪类,react脚手架当中内置了css modules的配置,咱们能够间接将css的文件定义为 xxx.module.css,在xxx.module.css文件中,还是依照以前的css编写形式编写,不同点在于jsx页面中定义className,先引入该css文件,而后定义类名以对象的模式定义
import style from './index.module.css'return(<div className={style.title}> hello react</div>)
这样定义的款式是一个不会反复的字符
这样一种定义款式的形式可能比拟无效的解决款式重叠的问题,麻烦之处就是每次编写款式的时候须要通过对象的语法来定义,并且不反对动静的设置款式。
那么就有了第四种形式,css in js,这是一种代码的理念,react中html和js没有拆散,那么css也能够不拆散,以js的形式来编写css,使css的编写更加的灵便,既能够像之前写css一样编写,又能够动静的获取属性。这种编写形式须要依赖其它库,这里应用罕用的 styled-components来演示。
应用 styled-components之前须要对es6模板字符串的一种语法有理解,咱们能够应用模板字符串来对字符串和属性进行拼接,在此之前的拼接可能都须要应用 +
const name = 'kiki'const age = '18'const user = `my name is ${name}, age is ${age}`console.log(user) // my name is kiki, age is 18
但模板字符串还有一种用法,就是它能够像小括号一样调用函数,并且参数以肯定的规定传递给函数
let name = 'kiki', age = 18function foo(...args){ console.log(args)}foo`hello`foo`my name is ${name}, age is ${age} `
基于模板字符串的这种应用形式,咱们来看看 styled-components 如何应用,先从styled-components的默认裸露中引入函数,创立一个div标签,并在模板字符串中定义款式,最初将创立的组件替换div标签,通过js定义的组件都能够抽取到一个独自的js文件当中,这里为了演示不便,就写在了一起。
import React, { PureComponent } from 'react'import styled from 'styled-components'const DivStyle = styled.div` background-color: gray; color: #fff; font-size: 20px;`export default class Profile extends PureComponent{ render(){ return(<div> <DivStyle>我是Profile组件的内容</DivStyle> </div>) }}
这样看起来编写形式更为简单了,但其实它还有很多好用的形式,除了应用款式,咱们可能还对有些标签要做一些别的属性设置,以及咱们须要通过以后页面保护的state属性来辨别款式的展现,在定义款式的时候,value值以函数的模式从props中获取属性
import React, { PureComponent } from 'react'import styled from 'styled-components'const InputStyle = styled.input.attrs({ type: 'text', placeholder: '请输出内容',})` color: ${props => props.color}`export default class Deliver extends PureComponent{ constructor(props){ super(props) this.state = { color: 'purple' } } render(){ return(<p> <InputStyle type="password" color={this.state.color}/> </p>) }}
款式当中,如果有反复的定义款式形式,要么须要定义多个className,要么就得反复定义,styled-components提供了继承的形式使款式能够复用,通过styled-components中默认裸露的导出函数,间接传入已定义好款式的组件
import React, { PureComponent } from 'react'import styled from 'styled-components'const DivStyle = styled.div` background-color: gray; color: #fff; font-size: 14px;`const RecommondStyle = styled(DivStyle)` font-size: 20px;`export default class Profile extends PureComponent{ render(){ return(<div> <DivStyle> hello styled-components </DivStyle> <RecommondStyle> style属性的继承 </RecommondStyle> </div> ) }}
另外,还能够给最外层的组件定义一个主题,这样它定义的款式子元素都能够从props中获取到
// 父组件import { ThemeProvider } from 'styled-components'export default class Home extends PureComponent{ render(){ return(<ThemeProvider theme={{color: 'brown'}}> <About/> </ThemeProvider>) }}// 子组件import React, { PureComponent } from 'react'import styled from 'styled-components'const DivStyle = styled.div` color: ${props => props.theme.color};`export default class About extends PureComponent{ render(){ return(<DivStyle> style设置主题 </DivStyle> ) }}
这样一种css的编写形式使得css的代码更像js,十分的灵便,也更具备复用性。
以上四种款式在react当中的定义形式是比拟罕用的,能够依据状况联合应用~