CSS Modules
Есть много способов написать стили в React, наиболее распространенными являютсяCSS modules
, Этот метод объединяет стили и компоненты CSS, а затем применяет их непосредственно в компонентах, структура каталогов:
|—src
| |_components
| |_ButtonComponent
| |_Button.jsx
| |_button.sass
Конкретный пример:css mudules in react
Видно, что стили, применяемые через модуль, имеют вид:
# 1.先引入对应模块的样式
import styles from './GlobalSelectors.css';
# 2.使用 className={styles.container} 这种形式表示模块class名
# 而 className="text-left" 这种形式则表示全局下的选择器
export default class GlobalSelectors extends Component {
render() {
return (
<div className={ styles.container }>
<p className="text-left">Global Selectors</p>
</div>
);
}
}
// css文件为 GlobalSelectors.css
.container {
border-width: 2px;
border-style: solid;
border-color: brown;
padding: 0 20px;
margin: 0 6px;
max-width: 400px;
}
# ':global' 表示该类为全局作用域下的
.container :global .text-left {
float: left
}
сами модули css нужныcss-loaderДля привязки это может представлять недостатки:
- должен использовать
camelCase
назвать имена классов css - при введении в
className
необходимо использовать во времяstylesобъект - Модули CSS, смешанные с глобальными классами CSS, могут быть сложными в управлении
- Ссылки на модули CSS с неиспользуемыми определениями не будут вызывать предупреждения.
И компонент react css Modules передается черезstyleName
МОДУЛИ CSS будут загружены автоматически.
react-css-modules
Использование react-css-modules решит проблему css-модулей выше, например:
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './tabel.sass'
class Table extends React.Component {
render() {
return (
# className 表示全局类名
# styleName 表示模块类名
<div styleName="table" className="tabel--info">
<div styleName="row">
<div styleName="cell">A0</div>
<div styleName="cell">B0</div>
</div>
</div>
);
}
}
# CSSModules 对组件进行修饰
export default CSSModules(Table, styles);
Ниже приведены конкретные этапы реализации и меры предосторожности.
1. Установка
Установить через нпм:
npm install --save react-css-modules
2. конфигурация веб-пакета
Этот пакет требуетstyle-loader | css-loader
1. Настройте файл css
Для этапа разработки:
# 注意 loaders 为复数
{
test: /\.css$/,
loaders: [
'style?sourceMap',
'css?modues&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
]
}
Для стадии продукта:Используйте версию 2.xextract-text-webpack-plugin
npm install --save-dev extract-text-webpack-plugin@2
npm install --save-dev resolve-url-loader post-loader
// webpack.config.js file
var ExtractTextPlugin = require('extract-text-webpack-plugin');
# 注意 loader 为单数
{
test: /\.css$/,
loader: ExtractTextPlugin({
notExtractLoader: 'style-loader',
loader: 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base4:5]!resolve-url!postcss'
})
}
# 配置ExtractTextPlugin
plugins: [
// ...
new ExtractTextPlugin({
filename: 'app.css',
allChunks: true
})
]
2. Для использования sass или других препроцессоров
Установите необходимые загрузчики:
npm install --save-dev resolve-url-loader sass-loader node-sass
// 不使用sourceMap
{
test: /\.sass$/,
loaders: [
'style',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'resolve-url',
'sass'
]
}
// 使用sourceMap
{
test: /\.sass$/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'resolve-url',
'sass?sourceMap'
]
}
Конечно, конфигурация этапа продукта также похожа
3. Используйте «стили», чтобы переопределить стили компонентов
Например:
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';
class Table extends React.Component {
render () {
return <div styleName='table'>
<div styleName='row'>
<div styleName='cell'>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
export default CSSModules(Table, styles);
Это распространенный способ написания, если вы хотите переопределить стили в стилях, вы можете использовать его в компонентеstyles
чтобы переопределить стили компонента:
# 引入自定义样式
import customStyles from './table-custom-styles.css';
# 使用 styles属性来重写之前的样式
<Table styles={customStyles} />
4. Циклы и подкомпоненты
styleNameНельзя использовать для оформления подкомпонентов в компонентах, таких как:
import React from 'react';
import CSSModules from 'react-css-modules';
import List from './List';
import styles from './table.css';
class CustomList extends React.Component {
render () {
let itemTemplate;
# 使用styleName 来修饰CustomList组件的子组件List
# 这是不允许的
itemTemplate = (name) => {
return <li styleName='item-template'>{name}</li>;
};
return <List itemTemplate={itemTemplate} />;
}
}
export default CSSModules(CustomList, styles);
Его можно переписать двумя способами:
метод 1:Используйте свойство стилей
import React from 'react';
import CSSModules from 'react-css-modules';
import List from './List';
import styles from './table.css';
class CustomList extends React.Component {
render () {
let itemTemplate;
# 使用styles属性,从父组件传递下去即可
itemTemplate = (name) => {
return <li className={this.props.styles['item-template']}>{name}</li>;
};
return <List itemTemplate={itemTemplate} />;
}
}
export default CSSModules(CustomList, styles);
Способ 2:Вызовите CSSModules внутри родительского компонента, чтобы украсить дочерний компонент:
import React, {Component} from 'react';
impot CSSModules from 'react-css-modules';
import List from './List';
import styles from './tabel.css';
class CustomList extends Component {
render() {
let itemTemplate;
itemTemplate = (name) => {
return <li styleName="item-template">{name}</li>;
};
# 内部调用CSSModules
itemTemplate = CSSModules(itemTemplate, this.props.styles);
return <List itemTemplate={itemTemplate} />;
}
}
export default CSSModules(CustomList, styles);
5. Опция CSSModules
Существует 2 способа написания CSSModules:
CSSModules(Component, styles, options)
// 或者
CSSModules(Component, styles)
options :
1.allowMultiple: по умолчанию ложно
Разрешить ли объявлять несколько классов, false означает, что это запрещено:
<div styleName='foo bar' /> // 不允许则报错
2.errorWhenNotFount: Значение по умолчанию верно,
Будет сообщено об ошибке, если имя стиля не найдено в модулях css.
6. Используйте глобальный CSS
:global .foo {
// ...
}
Это меньше используется
7. Используйте атрибут стилей для необязательных имен классов
Мы часто сталкиваемся с такой ситуацией с именем класса:
<div className={this.props.showMsg ? 'msg--visble': 'msg--hidden'}>
</div>
использовать реагирующие css-модулиКак справиться с такой проблемой?
Ключ должен бытьCSSModulesНаследование декорированных компонентовstyles
Свойства, используемые для сопоставления css-модулей и css-классов, а именно:
class App extends React.Component {
render() {
<div>
<p styleName='foo'></p>
<p className={this.props.styles.foo}></p>
</div>
}
}
В этом примереstyleName='foo'
а такжеclassName={this.props.styles.foo}
эквивалентны! ! !
Итак, решение вышеуказанной проблемы:
class App extends Component {
// ...
render() {
# 先声明这个变量
let visible = this.props.showMsg ? 'msg-visible' : 'msg-hidden';
return (
<div
# 然后在这用className来代替styleName
# 注意因为visible含有 '-'等字符,所以使用[]的方式
className={this.props.styles[visible]}
>
...
</div>
)
}
}
Суммировать
- react-css-modules github
- css modules examples
- Научитесь писать, когда className изменяется вместе с событиями (статья 7)
- Основная цель - научиться следующему способу написания стилей в реакции.
- Как настроить загрузчики, связанные с CSS, в веб-пакете