引言:
A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.
CSS模块就是所有的类名都只有局部作用域的CSS文件。
CSS模块化:
1、webpack.config.js中配置
const path = require("path"); const htmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: path.join(__dirname, "./src/main.js"), output: { path: path.join(__dirname, "./dist"), filename: "bundle.js", }, plugins: [ // 插件 new htmlWebpackPlugin({ template: path.join(__dirname, "./src/index.html"), filename: "index.html", }), ], module: { rules: [ /* 注意: 1、通过为css-loader添加modules参数,启用CSS的模块化 2、localIdentName用来控制className名称的长度。hash值取5位 例如:CommenItem_box-7ef23 */ { test: /\.css$/, use: [ "style-loader", "css-loader?modules&localIdentName=[name]_[local]-[hash:5]", ], }, { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }, { test: /\.(png|gif|bmp|jpg)$/, use: "url-loader?limit=5000" }, { test: /\.jsx?$/, use: "babel-loader", exclude: /node_modules/ }, ], }, };
2、CommentList.jsx 和 CommentList.css
--------CommentList.jsx------- import CommenList from "../css/CommenList.css"; export default class CommentList extends React.Component { constructor(props) { super(props); //定义一个当前评论列表组件的私有数据 this.state = { cmts: [ { user: "张大仙", content: "王者峡谷见" }, { user: "一眼万年", content: "刺激战场我最强" }, { user: "安其拉", content: "收起你的怜悯" }, { user: "凯帝", content: "希望天下无仇" }, { user: "李白", content: "一尊清酒,一把宝剑" }, { user: "牛魔", content: "平天大圣,不服来战" }, { user: "程咬金", content: "战斗,哪怕只剩最后一滴血" }, ], }; } //在【有状态组件】中,render函数是必须的,表示渲染哪些虚拟DOM元素并展示出来 render() { console.log("this.state:" + JSON.stringify(this.state)); /* 注意: 1、我们可以直接在JSX语法内部,使用数组的map函数,来遍历数组的每一项, 并使用map返回操作后的最新的数组 */ return ( <div> <h1 className="title">评论列表</h1> {this.state.cmts.map((item, i) => { return ( /* <CommentItem user={item.user} content={item.content} key={i} ></CommentItem> */ <CommentItem {...item} key={i}></CommentItem> ); })} </div> ); } } ------CommentList.css----- /* 注意: 1、当使用CSS模块化之后,这里所有的类名都是私有的,如果想要把类名设置 成一个全局的一个类,可以把这个类名用:global()包裹起来 2、当使用:global()设置了全局的类样式之后,这个类不会被重命名 */ :global(.title) { color: red; text-align: center; font-weight: 200; }
3、CommentItem.jsx 和 CommentItem.css
--------CommentItem.jsx-------- import React from "react"; import cmtItemStyles from "./cmtItemStyles.js"; /* 这种导入方式 import '../路径' ,并不是CSS的模块化导入 */ //import "../css/CommenItem.css"; /* 注意: 1、CSS的模块化导入 2、默认情况下,如果没有为CSS启用模块化,则受到的itemStyles是个空对象 因为.css样式表中不能直接通过JS的export default导出对象 */ import CommenItemStyle from "../css/CommenItem.css"; console.log("CommenItemStyle" + JSON.stringify(CommenItemStyle)); //封装一个评论【无状态组件】 export default function CommentItem(props) { //样式的右方优化方式1: const boxStyle = { fontSize: 16, color: "purple", }; //样式的优化方式2: const inlineStyles = { boxStyle2: { fontSize: 14, color: "red", }, }; let date = new Date(); let Y = date.getFullYear(); let M = date.getMonth() + 1; let D = date.getDay(); return ( /* 1、如果要使用style属性,为JSX语法创建的DOM元素设置样式,不能像网页中 那样写,而是要使用js语法来写 2、外层{}表示是JS代码;内层的{}是指用JS对象来表示 3、在style的样式规则中,如果属性值的单位是px,则可以省略px,直接写一个数值即可 */ <div className={CommenItemStyle.box}> {/* 注意: 1、如果在main.js中引入的样式中className和组件中有重名的,那么就会有问题, vue中有scoped指令,但是react中并没有指令的概念 解决方案: 2、CSS的模块化处理 3、当启用CSS模块化之后,导入样式表的带的itemStyles就变成了一个样式对象, 其中属性名是在样式表中定义的类名,属性值是自动生成的一个复杂的类名. 为了防止类名冲突 */} <h1 className={CommenItemStyle.title}>评论人:{props.user}</h1> <h2 className={CommenItemStyle.body}>评论内容:{props.content}</h2> <h2 className={CommenItemStyle.time}> 时间:{Y + "年" + M + "月" + D + "日"} </h2> </div> ); } --------CommentItem.css-------- .box { border: 1px solid #ccc; padding-left: 15px; box-shadow: 0 0 6px #ccc; display: flex; justify-content: space-between; margin: 10px 0; } .title { color: purple; font-size: 14px; padding: 15px 0; } .body, .time { font-size: 14px; color: red; padding: 15px 10px; }
commentItemStyle结果: