使用一個小例子來演示React中樣式的使用,如下圖,做一個靜態的評論列表組件:
1.創建兩個JSX文件:CmtItem.jsx和CmtList.jsx
CmtList.jsx:
import React from 'react'; //導入評論項子組件 import CmtItem from '@/components/CmtItem' //使用class關鍵字定義父組件 export default class CmtList extends React.Component{ constructor(){ super(); this.state = { //這是評論列表數據 CommentList: [ {id: 1, user: "張三", content: "哈哈,沙發" }, {id: 2, user: "李四", content: "哈哈,板凳" }, {id: 3, user: "王五", content: "哈哈,涼席" }, {id: 4, user: "趙六", content: "哈哈,磚頭" }, {id: 5, user: "田七", content: "哈哈,熱炕頭" } ] } } render(){ return <div> <h1>這是評論列表組件</h1> {this.state.CommentList.map(item => { return <CmtItem {...item} key={item.id}></CmtItem> })} </div> } }
CmtItem.jsx:
import React from 'react'; //使用function構造函數定義普通的無狀態組件 export default function CmtItem(props){ return <div> <h1>評論人:{props.user}</h1> <p>評論內容:{props.content}</p> </div> }
index.js:
// 1.導入包 import React from 'react' import ReactDOM from 'react-dom' //導入評論項子組件 import CmtList from '@/components/CmtList' ReactDOM.render(<div> <CmtList></CmtList> </div>,document.getElementById('app'));
主要的框架已經搭建好了,如下圖:
2.現在要給該列表組件添加樣式:
(1)使用普通的style樣式,類似以下這種(注意與HTML標簽使用樣式的區別):
<h1 style = { { color: 'red', fontWeight: 200 } } ></h1>
下面是HTML標簽的語法,注意區別:
<h1 style = " color: red; font-weight: 200 " ></h1>
(2)將樣式對象和UI結構分離,例如:
//第一層封裝方式:將樣式對象和UI結構分離 const itemStyle = {border: '1px dashed #ccc', margin: '10px', padding: '10px', boxShadow: '0 0 #ccc'}; const userStyle = {fontSize: '14px'}; const contentStyle = {fontSize: '12px'}; //使用function構造函數定義普通的無狀態組件 export default function CmtItem(props){ return <div style = {itemStyle}> <h1 style = {userStyle}>評論人:{props.user}</h1> <p style = {contentStyle}>評論內容:{props.content}</p> </div> }
(3)合並成一個大的樣式對象,例如:
//第二種封裝方式:合並成一個大的樣式對象 const styles = { item: {border: '1px dashed #ccc', margin: '10px', padding: '10px', boxShadow: '0 0 #ccc'}, user: {fontSize: '14px'}, content: {fontSize: '12px'} } //使用function構造函數定義普通的無狀態組件 export default function CmtItem(props){ return <div style = {styles.item}> <h1 style = {styles.user}>評論人:{props.user}</h1> <p style = {styles.content}>評論內容:{props.content}</p> </div> }
(4)抽離為單獨的樣式模塊:創建一個style.js文件:
export default{ item: {border: '1px dashed #ccc', margin: '10px', padding: '10px', boxShadow: '0 0 10px #ccc'}, user: {fontSize: '14px'}, content: {fontSize: '12px'} }
然后再調用該文件(例如,CmtItem.jsx:):
//第三種封裝方式:抽離為單獨的樣式模塊 import styles from '@/components/styles.js' //使用function構造函數定義普通的無狀態組件 export default function CmtItem(props){ return <div style = {styles.item}> <h1 style = {styles.user}>評論人:{props.user}</h1> <p style = {styles.content}>評論內容:{props.content}</p> </div> }
(5)創建樣式表文件:cmtlist.css文件,首先需要安裝style-loader和css-loader並啟用css-modules:
●修改webpack.config.js配置文件,為css-loader添加參數
●在需要的組件中,import導入樣式表,並接收模塊化的CSS樣式對象
●在需要的HTML標簽上,使用className指定模塊化的CSS樣式對象
module: { //所有第三方模塊的配置規則 rules: [ {test: /\.js|jsx$/, use:'babel-loader', exclude: /node_modules/}, //注意:在配置babel-loader時,一定要加上exclude: /node_modules/,否則整個項目會報錯 //可以在css-loader之后通過?追加參數 //其中有個固定的參數modules,表示為普通的CSS樣式表啟用模塊化 {test: /\.css$/, use: ['style-loader', 'css-loader?modules']}, //打包處理css樣式表的第三方loader ] }
樣式表cmtlist.css:
.title{ color: red; font-size: 35px; font-weight: 200; text-align: center; } /*css模塊化只針對 類選擇器(例如.title) 和 ID選擇器(例如#id)生效,不會將標簽選擇器模塊化*/ .user{ font-size: 14px; } .content{ font-size: 12px; } .cmtbox{ border: 1px dashed #ccc; margin: 10px; padding: 10px; box-shadow: 0 0 10px #ccc; } /* 被 :global 包裹起來的類名不會被css-modules模塊化,而是會全局生效 被 :local 包裹起來的類名會被模塊化,默認情況下所有的類名和ID都是被模塊化的 */ :global(.test){ font-style: italic; }
調用樣式表,例如,CmtItem.jsx::
import React from 'react'; import cssobj from '@/css/cmtlist.scss' console.log(cssobj); //如果沒有啟用css-modules模塊化,則cssobj只是一個空對象,下面的引用樣式的方式應該是className="樣式名" //使用function構造函數定義普通的無狀態組件 export default function CmtItem(props){ return <div className={cssobj.cmtbox}> <h1 className={cssobj.user}>評論人:{props.user}</h1> <p className={cssobj.content}>評論內容:{props.content}</p> </div> }
css模塊化后控制台輸出的cssobj對象的內容如下:類名的值是隨機碼,如果想要自定義生成類名格式,可以使用localIdentName
使用localIdentName自定義生成類名格式,可選的參數有:
●[path] 表示樣式表相對於項目根目錄所在的路徑
●[name] 表示樣式表文件名稱
●[local] 表示樣式的類名定義名稱
●[hash:length] 表示32位的hash值
//css配置如下 {test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: { localIdentName: "[path][name]-[local]-[hash:5]" } } }, { loader: 'sass-loader' } ]} //打包處理scss文件的loader