React學習之旅Part6:React中JSX的CSS樣式(行內樣式、封裝樣式、抽取樣式表模塊)、模塊化解決css作用域問題、loader處理字體文件和scss和less

一、CSS樣式

在React中 JSX的虛擬DOM組件同樣可以設置樣式 且設置方式與普通的寫法大同小異

CSS樣式有兩種寫法 分別爲行內樣式封裝樣式

行內樣式:

在JSX中 行內樣式不能爲style設置字符串格式的值 而是對象鍵值對類型的值
若出現連字符 則從第二個單詞開始開頭要大寫 否則必須爲字符串格式
在行內樣式中 若是純數值類型的樣式 則可以不用引號進行包裹 但若爲字符串類型的樣式 則必須用引號包裹

例如:

export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 style={{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"}}>你好</h1>
	        <p style={{fontSize:"12px"}}>...</p>
	    </div>
	}
}

我們看見 在上面的例子中 有兩個花括號
其中 外面的花括號代表裏面承載的是JSX語法內容
而裏面的花括號代表CSS樣式屬性的對象鍵值對類型

抽取樣式

當然 行內的CSS樣式造成代碼過於紊亂 可以抽取樣式 以使代碼更加清晰化
使樣式對象與結構進行分離

例如:

const myStyleOne={color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"}
const myStyleTwo={fontSize:"12px"}

export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 style={myStyleOne}>你好</h1>
	        <p style={myStyleTwo}>...</p>
	    </div>
	}
}

二次封裝

若有多個樣式對象 還可以再進行封裝 將它們合併成一個更大的樣式對象

例如:

const myStyle={
	one:{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"},
	two:{fontSize:"12px"}
}

export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 style={myStyle.one}>你好</h1>
	        <p style={myStyle.two}>...</p>
	    </div>
	}
}

抽離爲樣式表模塊文件

myStyles.js:

export default {
	one:{color:"red",fontSize:"25px",fontWeight:200,textAlign:"center"},
	two:{fontSize:"12px"}
}

Hello.jsx:

import React from 'react';

// 導入樣式表模塊
import myStyles from "@/components/myStyles"

export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 style={myStyle.one}>你好</h1>
	        <p style={myStyle.two}>...</p>
	    </div>
	}
}

CSS樣式表

但 在JS中寫CSS樣式 少了一些代碼提示 還是不方便
可以在CSS文件中寫樣式 然後導入到JS文件中

1、安裝Loader:

爲了使Webpack能夠處理CSS格式的文件 需要安裝第三方Loader
安裝style-loadercss-loader

npm i style-loader css-loader -D

安裝完畢之後 還是在webpack.config.js的module的rules屬性裏進行配置第三方匹配規則:

module:{
        // 第三方匹配規則
        rules:[
            {test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
            {test:/\.css$/,use:["style-loader","css-loader"]} // 匹配css樣式文件
        ]
    },

loader的調用順序是從右往左 先用css-loader進行處理css文件 處理完畢再交給style-loader進行二次處理 最後將處理結果交給Webpack打包

2、loader配置完畢之後 在頁面中使用:

hello.css:

.one{
	color:"red",
	fontSize:"25px",
	fontWeight:200,
	textAlign:"center"
},

.two{
	fontSize:"12px"
}

Hello.jsx:

import React from 'react';

// 導入組件需要的樣式表
import mycss from "@/css/hello.css"

export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 className="one">你好</h1>
	        <p className="two">...</p>
	    </div>
	}
}

二、作用域和模塊化

導入的CSS樣式表的樣式作用域是全局(即整個項目)都生效的 因爲樣式表沒有作用域
這樣可能會導致樣式衝突問題

React並沒有類似於Vue的scoped指令 React壓根沒有指令的概念
在React中 可以藉助Webpack 爲css樣式表啓用模塊化 以解決作用域衝突問題

webpack.config.js中進行配置:
在css-loader後跟上一個modules即可開啓模塊化

module:{
        // 第三方匹配規則
        rules:[
            {test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
            {test:/\.css$/,use:["style-loader","css-loader?modules"]} // 爲css-loader追加modules參數 以代表爲css樣式表啓用模塊化
        ]
    },

開啓了模塊化之後 在css文件中的每個類和id 都會成爲一個隨機生成的字符串鍵值對
像這樣:在這裏插入圖片描述
就是css中的類名
就是這個隨機字符串

那麼 若要使用該類 只需要用引入的css文件對象.類名即可

像這樣:

import React from 'react';
import mycss from "@/css/hello.css"
export default class Hello extends React.Component
{
    constructor()
    {
        super();
    }
	render()
	{
	    return <div>
	        <h1 className={mycss.one}>你好</h1>
	        <p className={mycss.two}>...</p>
	    </div>
	}
}

如此 實現了css屬性的唯一性

值得注意的是:css模塊化只支持類選擇器id選擇器 除此之外 其它選擇器並不會被模塊化
因此 其它選擇器依舊是會全局生效的

自定義模塊化類名/id名

默認生成的隨機字符串不容易看出是哪個css文件中的哪個類/id的屬性

爲此 Webpack還支持自定義類名
使用localIdentName屬性以自定義生成的類名格式

參數:

  • [path]:樣式表相當於項目根目錄所在路徑(動態改變)
  • [name]:樣式表文件名稱
  • [local]:樣式的類名定義名稱
  • [hash:length]:32位的hash值

例如:

{test:/\.css$/,use:[
                {loader:"style-loader"},
                {
                    loader:"css-loader",
                    options:{
                        modules:{
                            localIdentName:"[path][name]-[local]-[hash:base64:5]"
                        }
                    }
                }
            ]}

如此配置後 隨機類名將會變成形如src-css-hello-one-JQupRsrc-css-hello-two-39yRX的樣子了

設置指定類名/id名是否被模塊化

使用:global():local()可以指定類名或id名是否被模塊化

---------- :global() ----------
例如:
:global(.test)
{
font-style: italic;
}
這樣 test類就不會被模塊化了 因此也不會變成隨機的字符串了
此時 可以在標籤上添加className="test"以設置樣式

當一個標籤上既要使用JSX語法的類名 又要使用字符串的類名時
比如這樣:className={cssobj.title} className=“test”
此時 後面的className屬性將會覆蓋前面的同名屬性

有兩種方法可以寫到一起

  • 方法一是拼接字符串className={cssobj.title+" test"}(:在test前面有個空格 用於分隔)
  • 方法二是數組形式className={[cssobj.title,"test"].join(" ")}(:join代表使用空格進行連接 否則默認是用逗號連接的)

---------- :local() ----------
和:global()相反 被:local()包裹的類名被模塊化
在開啓css模塊化之後 默認是所有類名/id名全添加了:local() 即全部都會被模塊化

三、loader的安裝及使用

loader處理字體文件

安裝url-loader:

npm i url-loader file-loader -D

(url-loader內部依賴於file-loader)

在webpack.config.js中進行配置:

module:{
        // 第三方匹配規則
        rules:[
        	{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
            {test:/\.ttf|woff|woff2|eot|svg$/,use:"url-loader"}
        ]
    },

loader處理scss和less文件

安裝:

npm i sass-loader node-sass -D

(sass-loader內部依賴於node-sass)

安裝完畢之後 在webpack.config.js中進行配置:

module:{
        // 第三方匹配規則
        rules:[
        	{test:/\.js|jsx$/,use:"babel-loader",exclude:/node_modules/},
            {test:/\.scss$/,use:["style-loader","css-loader","sass-loader"]}
        ]
    },

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章