一、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-loader和css-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-JQupR和src-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"]}
]
},