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

 

posted @ 2019-12-12 17:29  浮华夕颜  Views(9666)  Comments(0Edit  收藏  举报