现在我们已经学会了在React中通过import直接引入外部的CSS样式表,但这并不是React中使用CSS的唯一方式,这里我们简单的罗列几种React中设置样式的方式。
内联样式
在React中可以直接通过标签的style属性来为元素设置样式。style属性需要的是一个对象作为值,来为元素设置样式。
<div style={{color:'red'}}>
我是Div
</div>
传递样式时,需要注意如果样式名不符合驼峰命名法,需要将其修改为符合驼峰命名法的名字。比如:background-color改为backgroundColor。
如果内联样式编写过多,会导致JSX变得异常混乱,此时也可以将样式对象定义到JSX外,然后通过变量引入。
样式过多,JSX会比较混乱:
const StyleDemo = () => {
return (
<div style={{color:'red', backgroundColor:'#bfa', fontSize:20, borderRadius:12}}>
我是Div
</div>
);
};
export default StyleDemo;
可以这样修改:
import React from 'react';
const StyleDemo = () => {
const divStyle = {color: 'red', backgroundColor: '#bfa', fontSize: 20, borderRadius: 12}
return (
<div style={divStyle}>
我是Div
</div>
);
};
export default StyleDemo;
相比第一段代码来说,第二段代码中JSX结构更加简洁。
在内联样式中使用state
设置样式时,可以根据不同的state值应用不同的样式,比如我们可以在组件中添加一个按钮,并希望通过点击按钮可以切换div的边框,代码可以这样写:
import React, {useState} from 'react';
const StyleDemo = () => {
const [showBorder, setShowBorder] = useState(false);
const divStyle = {
color: 'red',
backgroundColor: '#bfa',
fontSize: 20,
borderRadius: 12,
border: showBorder?'2px red solid':'none'
};
const toggleBorderHandler = ()=> {
setShowBorder(prevState => !prevState);
};
return (
<div style={divStyle}>
我是Div
<button onClick={toggleBorderHandler}>切换边框</button>
</div>
);
};
export default StyleDemo;
上例中添加一个新的state,命名为showBorder,代码是这样的const [showBorder, setShowBorder] = useState(false);
当该值为true时,我们希望div可以显示一条2像素的红色边框,当为false时,我们希望div没有边框。默认值为false。
divStyle的最后一个属性是这样设置的border: showBorder?'2px red solid':'none'
,这里我们根据showBorder的值来设置border样式的值,如果值为true,则设置边框,否则边框设置为none。
toggleBorderHandler
是负责修改showBorder的响应函数,当我们点击按钮后函数会对showBorder进行取反,这样我们的样式就可以根据state的不同值而呈现出不同的效果了。
外部样式表
外部样式是将样式编写到外部的css文件中,然后直接通过import进行引入,上述案例修改为外部样式表是这个样子:
StyleDemo.css
.myDiv{
color: red;
background-color: #bfa;
font-size: 20px;
border-radius: 12px;
}
.redBorder{
border: 2px red solid;
}
StyleDemo.js
import React, {useState} from 'react'; import './StyleDemo.css'; const StyleDemo = () => { const [showBorder, setShowBorder] = useState(false); const toggleBorderHandler = ()=> { setShowBorder(prevState => !prevState); }; return ( <div className={`myDiv${showBorder?' redBorder':''}`}> 我是Div <button onClick={toggleBorderHandler}>切换边框</button> </div> ); }; export default StyleDemo;
上边的案例中,将样式编写到了外部的css文件中,然后通过import引入到了当前模块中。在JSX中通过为元素添加了class使得样式生效。同时,在设置class时使用了模板字符串,根据showBorder的值判断是否添加redBorder这个类。
上边两个案例中无论是内联样式还是外部样式表最终的实现效果都是一样的,但要是让我从这两种方式中选的话我更加倾向于选择第二种,第二种方式中将JSX和CSS分别写到了不同的文件中,我们维护起来更加的方便。
但是以这种方式使用样式也会存在一个问题,直接通过import引入的样式都是全局样式,如果不同的样式表中出现了相同的类名,会出现相互覆盖情况,这一点要尤为注意!
CSS Module
如果没有类名冲突的问题,外部CSS样式表不失为是一种非常好的编写样式的方式。为了解决这个问题React中还为我们提供了一中方式,CSS Module。
我们可以将CSS Module理解为外部样式表的一种进化版,它的大部分使用方式都和外部样式表类似,不同点在于使用CSS Module后,网页中元素的类名会自动计算生成并确保唯一,所以使用CSS Module后,我们再也不用担心类名重复了!
使用方式
CSS Module在React中已经默认支持了(前提是使用了react-scripts),所以无需再引入其他多余的模块。使用CSS Module时需要遵循如下几个步骤:
- 使用CSS Module编写的样式文件的文件名必须为
xxx.module.css
- 在组件中引入样式的格式为
import xxx from './xxx.module.css'
- 设置类名时需要使用
xxx.yyy
的形式来设置
请看案例:
/* StyleDemo.module.css */ .myDiv{ color: red; background-color: #bfa; font-size: 20px; border-radius: 12px; }
/* StyleDemo.js */ import styles from './StyleDemo.module.css'; const StyleDemo = () => { return ( <div className={styles.myDiv}> 我是Div </div> ); }; export default StyleDemo;
这就是一个简单的CSS Module的案例,设置完成后你可以自己通过开发者工具查看元素的class属性,你会发现class属性和你设置的并不完全一样,这是因为CSS Module通过算法确保了每一个模块中类名的唯一性。
总之,相较于标准的外部样式表来说,CSS Module就是多了一点——确保类名的唯一,通过内部算法避免了两个组件中出现重复的类名,如果你能保证不会出现重复的类名,其实直接使用外部样式表也是一样的。
打卡
请教一下,css module,要是写less的话,就是命名外部文件为**.module.less吗