1. 程式人生 > >React 專案中的一種樣式管理方式: stylus + react-css-modules

React 專案中的一種樣式管理方式: stylus + react-css-modules

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專案針對樣式問題上有所參考作用,一起加油!