一、CSS样式
在React中 JSX的虚拟DOM组件同样可以设置样式 且设置方式与普通的写法大同小异
CSS样式有两种写法 分别为行内样式 和 封装样式
行内样式:
在JSX中 行内样式不能为style设置字符串格式的值 而是对象键值对类型的值
若出现连字符 则从第二个单词开始开头要大写 否则必须为字符串格式
在行内样式中 若是纯数值类型的样式 则可以不用引号进行包裹 但若为字符串类型的样式 则必须用引号包裹
例如:
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 style={{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"}}>你好</h1>
<p style={{fontSize:"12px"}}>我...</p>
</div>
}
}
我们看见 在上面的例子中 有两个花括号
其中 外面的花括号代表里面承载的是JSX语法内容
而里面的花括号代表CSS样式属性的对象键值对类型
抽取样式
当然 行内的CSS样式造成代码过于紊乱 可以抽取样式 以使代码更加清晰化
使样式对象与结构进行分离
例如:
const myStyleOne={color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"}
const myStyleTwo={fontSize:"12px"}
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 style={myStyleOne}>你好</h1>
<p style={myStyleTwo}>我...</p>
</div>
}
}
二次封装
若有多个样式对象 还可以再进行封装 将它们合并成一个更大的样式对象
例如:
const myStyle={
one:{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"},
two:{fontSize:"12px"}
}
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 style={myStyle.one}>你好</h1>
<p style={myStyle.two}>我...</p>
</div>
}
}
抽离为样式表模块文件
myStyles.js:
export default {
one:{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"},
two:{fontSize:"12px"}
}
Hello.jsx:
import React from 'react';
// 导入样式表模块
import myStyles from "@/components/myStyles"
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 style={myStyle.one}>你好</h1>
<p style={myStyle.two}>我...</p>
</div>
}
}
CSS样式表
但 在JS中写CSS样式 少了一些代码提示 还是不方便
可以在CSS文件中写样式 然后导入到JS文件中
1、安装Loader:
为了使Webpack能够处理CSS格式的文件 需要安装第三方Loader
安装style-loader和css-loader:
npm i style-loader css-loader -D
安装完毕之后 还是在webpack.config.js的module的rules属性里进行配置第三方匹配规则:
module:{
// 第三方匹配规则
rules:[
{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
{test:/\.css$/,use:["style-loader","css-loader"]} // 匹配css样式文件
]
},
loader的调用顺序是从右往左 先用css-loader进行处理css文件 处理完毕再交给style-loader进行二次处理 最后将处理结果交给Webpack打包
2、loader配置完毕之后 在页面中使用:
hello.css:
.one{
color:"red",
fontSize:"25px",
fontWeight:200,
textAlign:"center"
},
.two{
fontSize:"12px"
}
Hello.jsx:
import React from 'react';
// 导入组件需要的样式表
import mycss from "@/css/hello.css"
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 className="one">你好</h1>
<p className="two">我...</p>
</div>
}
}
二、作用域和模块化
导入的CSS样式表的样式作用域是全局(即整个项目)都生效的 因为样式表没有作用域
这样可能会导致样式冲突问题
React并没有类似于Vue的scoped指令 React压根没有指令的概念
在React中 可以借助Webpack 为css样式表启用模块化 以解决作用域冲突问题
在webpack.config.js中进行配置:
在css-loader后跟上一个modules即可开启模块化
module:{
// 第三方匹配规则
rules:[
{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
{test:/\.css$/,use:["style-loader","css-loader?modules"]} // 为css-loader追加modules参数 以代表为css样式表启用模块化
]
},
开启了模块化之后 在css文件中的每个类和id 都会成为一个随机生成的字符串键值对
像这样:
键 就是css中的类名
而值 就是这个随机字符串
那么 若要使用该类 只需要用引入的css文件对象.类名即可
像这样:
import React from 'react';
import mycss from "@/css/hello.css"
export default class Hello extends React.Component
{
constructor()
{
super();
}
render()
{
return <div>
<h1 className={mycss.one}>你好</h1>
<p className={mycss.two}>我...</p>
</div>
}
}
如此 实现了css属性的唯一性
值得注意的是:css模块化只支持类选择器和id选择器 除此之外 其它选择器并不会被模块化
因此 其它选择器依旧是会全局生效的
自定义模块化类名/id名
默认生成的随机字符串不容易看出是哪个css文件中的哪个类/id的属性
为此 Webpack还支持自定义类名
使用localIdentName属性以自定义生成的类名格式
参数:
- [path]:样式表相当于项目根目录所在路径(动态改变)
- [name]:样式表文件名称
- [local]:样式的类名定义名称
- [hash:length]:32位的hash值
例如:
{test:/\.css$/,use:[
{loader:"style-loader"},
{
loader:"css-loader",
options:{
modules:{
localIdentName:"[path][name]-[local]-[hash:base64:5]"
}
}
}
]}
如此配置后 随机类名将会变成形如src-css-hello-one-JQupR和src-css-hello-two-39yRX的样子了
设置指定类名/id名是否被模块化
使用:global()和:local()可以指定类名或id名是否被模块化
---------- :global() ----------
例如:
:global(.test)
{
font-style: italic;
}
这样 test类就不会被模块化了 因此也不会变成随机的字符串了
此时 可以在标签上添加className="test"以设置样式
当一个标签上既要使用JSX语法的类名 又要使用字符串的类名时
比如这样:className={cssobj.title} className=“test”
此时 后面的className属性将会覆盖前面的同名属性
有两种方法可以写到一起
- 方法一是拼接字符串:
className={cssobj.title+" test"}(注:在test前面有个空格 用于分隔) - 方法二是数组形式:
className={[cssobj.title,"test"].join(" ")}(注:join代表使用空格进行连接 否则默认是用逗号连接的)
---------- :local() ----------
和:global()相反 被:local()包裹的类名会被模块化
在开启css模块化之后 默认是所有类名/id名全添加了:local() 即全部都会被模块化
三、loader的安装及使用
loader处理字体文件
安装url-loader:
npm i url-loader file-loader -D
(url-loader内部依赖于file-loader)
在webpack.config.js中进行配置:
module:{
// 第三方匹配规则
rules:[
{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
{test:/\.ttf|woff|woff2|eot|svg$/,use:"url-loader"}
]
},
loader处理scss和less文件
安装:
npm i sass-loader node-sass -D
(sass-loader内部依赖于node-sass)
安装完毕之后 在webpack.config.js中进行配置:
module:{
// 第三方匹配规则
rules:[
{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
{test:/\.scss$/,use:["style-loader","css-loader","sass-loader"]}
]
},
本文详细介绍了在React中如何使用JSX处理CSS样式,包括行内样式、封装样式、抽离为样式表模块文件,并探讨了解决CSS作用域问题的模块化方法,以及如何通过loader处理字体文件、scss和less文件。

2862

被折叠的 条评论
为什么被折叠?



