React 專案中的一種樣式管理方式: stylus + react-css-modules
阿新 • • 發佈:2019-01-06
stylus 是一套 css 預處理框架,react專案可以通過 stylus 管理樣式檔案。react-css-modules 則主要用於實現對樣式的模組化引用,stylus 與 react-css-modules 配合使用可以實現一套對react專案的樣式管理方案。
在使用 stylus 前需要先對專案進行相應的配置,其步驟如下:
安裝Stylus:
安裝其所需的依賴包:
$ npm install stylus -S
$ npm install stylus-loader -S
暴露React配置檔案:
執行以下指令碼把配置檔案先暴露出來。
$ npm run eject
執行這段指令碼時,會詢問您是否確認暴露,因為該過程是不可逆的,選擇'Y'即可。若執行發生錯誤,需要刪掉專案中的跟蹤檔案,如使用HBuilder編譯器時會隨專案建立時生成.project跟蹤檔案,同時,最好先把專案全部提交一遍至Git(如果有使用的話),以防過程中發生異常。
修改配置檔案:
開啟config/webpack.config.dev.js,修改配置如下:
module: { strictExportPresence: true, rules: [ ... oneOf: [ ... { test: /\.styl$/, loaders: ['style-loader', 'css-loader', 'stylus-loader'] }, { // Exclude `js` files to keep "css" loader working as it injects // its runtime that would otherwise be processed through "file" loader. // Also exclude `html` and `json` extensions so they get processed // by webpacks internal loaders. exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/, /\.styl$/], loader: require.resolve('file-loader'), options: { name: 'static/media/[name].[hash:8].[ext]', }, } ] ] ... }
開啟config/webpack.config.prod.js,按上面的辦法同樣修改一遍,這樣build出來的檔案.styl檔案才會有效。
(小貼士)若想要build後能雙擊開啟index.html就可以看到頁面,則把修改publicPath為:
const publicPath = './';
執行以下程式碼測試效果:
// base.styl div{ color: red; p { color: blue; } } // App.js import React from 'react'; import './base.styl'; class App extends React.Component { render() { return( <div> Hello World! <p>This is Paragraph!</p> </div> ); } } export default App;
啟動專案,效果如圖所示:
例項地址:https://github.com/smallH/react-stylus.git
這種引用方法有個缺點,所引用的樣式將會是全域性樣式。若想引用成元件私有的樣式檔案,可以使用react-css-modules。
聯合 react-css-modules 和 Stylus實現元件私有樣式引用:
初始化
$ npm install react-css-modules -S
開啟config/webpack.config.dev.js,修改配置如下:
{
test: /\.styl$/,
loaders: [
'style-loader',
'css-loader?modules&localIdentName=[name]-[hash:base64:5]',
'stylus-loader'
]
},
{
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/, /\.styl$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
}
使用:
import React from 'react'
import styles from './index.styl'
import CSSModules from 'react-css-modules'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as AllActions from '@/reducers/Auth/actions'
import PropTypes from 'prop-types'
class Login extends React.Component {
static propTypes = {
actions: PropTypes.object.isRequired
}
constructor(props) {
super(props)
this.state = {}
}
visitor = () => {
this.props.actions.signIn("");
this.props.history.push({
pathname: '/home/welcome'
})
}
manager = () => {
this.props.actions.signIn("API-TOKEN20181214");
this.props.history.push({
pathname: '/home/welcome'
})
}
render() {
return(
<div id="login" styleName="login">
<div styleName="title">歡迎使用 react-redux-axios 前端框架</div>
<div styleName="nav">
<div styleName="btn" onClick={this.visitor}>遊客</div>
<div styleName="btn manager" onClick={this.manager}>管理員</div>
</div>
</div>
);
}
}
// 同樣實現propTypes效果
//Login.propTypes = {
// actions: PropTypes.object.isRequired
//}
const CSSLogin = CSSModules(Login, styles, {
allowMultiple: true
});
const mapDispatchToProps = (dispatch, ownProps) => ({
actions: bindActionCreators(AllActions, dispatch)
})
export default connect(null, mapDispatchToProps)(CSSLogin)
樣式檔案:
// index.styl
.login{
.title {
text-align: center;
font-size: 46px;
font-weight: bold;
margin-top: 200px;
}
.nav {
display: flex;
margin-top: 50px;
justify-content: center;
align-items: center;
}
.btn {
min-width: 140px;
text-align: center;
font-size: 24px;
cursor: pointer;
border-radius: 30px;
background-color: #009688;
color: white;
width: fit-content;
padding: 10px;
margin-top: 0px;
}
.manager {
margin-left: 20px;
color: gray;
background-color: transparent;
border: solid 1px #009688;
}
}
以上是react專案中樣式管理的其中一種方式,希望能對大家開發react專案針對樣式問題上有所參考作用,一起加油!