React中设置样式
使用一个小例子来演示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