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 = false
const 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 = 18
function 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当中的定义方式是比较常用的,可以根据情况结合使用~

一文了解react中定义样式(css/less/sass)的常用方法的更多相关文章

  1. react中怎么写css样式?

    JSX基本语法中关于react如何写css样式主要有三种方法 1.基于class --(className) 基于className ,通过className在style中给该class名的DOM元素 ...

  2. javascript中的style只能取到在HTML中定义的css属性

    如果在css中定义的 li{ width:100px; left:100px; top:; position:absolute; font-style:normal; } 这样执行: oli[0].s ...

  3. 【CSS】如何在一个页面中引入样式css

    CSS(Cascading Style Sheet)又叫层叠样式表.是我们学习前端必不可少的一门语言,学习它其实就是为了学会如何去更改页面标签的样式.目前使用最广的是css3,但同样的,他是从css2 ...

  4. 聊一聊 React 中的 CSS 样式方案

    和 Angular,Vue 不同,React 并没有如何在 React 中书写样式的官方方案,依靠的是社区众多的方案.社区中提供的方案有很多,例如 CSS Modules,styled-compone ...

  5. 转 : CSS Modules详解及React中实践

    https://zhuanlan.zhihu.com/p/20495964 CSS 是前端领域中进化最慢的一块.由于 ES2015/2016 的快速普及和 Babel/Webpack 等工具的迅猛发展 ...

  6. 在react中实现CSS模块化

    react中使用普通的css样式表会造成作用域的冲突,css定义的样式的作用域是全局,在Vue 中我们还可以使用scope来定义作用域,但是在react中并没有指令一说,所以只能另辟蹊径了.下面我将简 ...

  7. React中的合成事件

    React中的合成事件 React自己实现了一套高效的事件注册.存储.分发和重用逻辑,在DOM事件体系基础上做了很大改进,减少了内存消耗,简化了事件逻辑,并最大程度地解决了IE等浏览器的不兼容问题. ...

  8. react 的定义组件(了解)

    react 中定义组件的方法 1. 定义组件 React.createClass() (被淘汰了) 定义组件中的函数 methods 的中的 this 统统指向 组件 2. 函数定义组件 定义的组件时 ...

  9. 在React中使用CSS Modules设置样式

    最近,一直在看React...那真的是一个一直在学的过程啊,从配置环境webpack,到基础知识jsx,babel,es6,没有一个不是之前没有接触的.其实,我内心是兴奋的啊,毕竟,活着就是要接触一些 ...

  10. React中引用CSS样式的方法

    相对于html中引用css的三种方法,react中也有三种方法,一一相对: 1. 行内样式:直接在组件内部定义 <div style={{width:'20px',height:'30px'}} ...

随机推荐

  1. drf重写authenticate方法实现多条件登录(源码分析)

    drf重写authenticate方法实现多条件登录(源码分析) 1. 思路 JWT拓展的登录视图中, 在接受到用户名和密码时, 调用的也是Django的认证系统中提供的authenticate()来 ...

  2. 雪球 app 实战(1)

    开头 因为理论篇结束之后,需要一个实战,估选用了雪球app作为一个作业 业务场景: 雪球 app 自选设置(入口位于 行情 模块) 作业内容 使用 百度脑图 编写 思维导图 [自选设置]模块的测试用例 ...

  3. 2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数。 (n<=1000,k<=100)。 来自微众。4.11笔试。

    2022-07-11:给定n位长的数字字符串和正数k,求该子符串能被k整除的子串个数. (n<=1000,k<=100). 来自微众.4.11笔试. 答案2022-07-11: 动态规划. ...

  4. 2022-02-04:组合总和 Ⅳ。 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证

    2022-02-04:组合总和 Ⅳ. 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 target 的元素组合的个数. 题目数据保证 ...

  5. 2021-11-21:map[i][j] == 0,代表(i,j)是海洋,渡过的话代价是2, map[i][j] == 1,代表(i,j)是陆地,渡过的话代价是1, map[i][j] == 2,代表

    2021-11-21:map[i][j] == 0,代表(i,j)是海洋,渡过的话代价是2, map[i][j] == 1,代表(i,j)是陆地,渡过的话代价是1, map[i][j] == 2,代表 ...

  6. 一个线上全文索引BUG的排查:关于类阿拉件数字的分词与检索

    说到全文检索的分词,多半讲到的是中(日韩)文分词,少有英文等拉丁文系语言,因为英语单词天然就是分词的. 但更少讲到阿拉伯数字.比如金额,手机号码,座机号码等等. 以下不是传统的从0开始针对mysql全 ...

  7. Nacos必知必会:这些知识点你一定要掌握!

    前言 Nacos 是一个开源的服务发现.配置管理和服务治理平台,是阿里巴巴开源的一款产品. Nacos 可以帮助开发者更好地管理微服务架构中的服务注册.配置和发现等问题,提高系统的可靠性和可维护性. ...

  8. centos linux系统安装详解

    打开vmware,版本差异区别不大 选择创建新的虚拟机 选择典型,是默认选项不用改,点击下一步 选择稍后安装操作系统(默认选项不用改),点击下一步 选择linux,并且版本改为centos 64位,点 ...

  9. Kubernetes GoRoutineMap工具包代码详解

    1.概述 GoRoutineMap 定义了一种类型,可以运行具有名称的 goroutine 并跟踪它们的状态.它防止创建具有相同名称的多个goroutine,并且在上一个具有该名称的 goroutin ...

  10. Java中读取用户输入的是谁?Scanner类

    前言 我们在初学 Java 编程的时候,总是感觉很枯燥乏味,想着做点可以交互的小系统,可以让用户自由输入,系统可以接收做出反映.这就要介绍一下 Java 中的 Scanner 类了. 一.Scanne ...