引言:
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結果: