React学习之旅Part6:React中JSX的CSS样式(行内样式、封装样式、抽取样式表模块)、模块化解决css作用域问题、loader处理字体文件和scss和less

本文详细介绍了在React中如何使用JSX处理CSS样式,包括行内样式、封装样式、抽离为样式表模块文件,并探讨了解决CSS作用域问题的模块化方法,以及如何通过loader处理字体文件、scss和less文件。

一、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-loadercss-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-JQupRsrc-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"]}
        ]
    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值