介绍
React 允许您直接使用style
属性设置组件样式。对于大多数情况,使用style
prop 传递 CSS 属性的对象就足够了。
但是,对于需要更苛刻的样式功能的情况,emotion
可以提供解决方案。emotion
是一个灵活且高性能的 CSS-in-JS 库。它接受字符串和对象,支持默认和扩展变量,并且通过额外的 Babel 插件甚至支持内联子选择器。
在本文中,您将构建一个使用@emotion/react
和@emotion/styled
包进行样式设置的 React 应用程序。
先决条件
要完成本教程,您需要:
- Node.js 的本地开发环境。遵循如何安装 Node.js 并创建本地开发环境。
注意:本文之前推荐了emotion
和react-emotion
包。现在几个版本之后,@emotion/react
和@emotion/styled
是现代的方法。
本教程已通过 Node v15.3.0、npm
v7.4.0、react
v17.0.1、@emotion/react
v11.1.4 和@emotion/styled
v11.0.0 验证。
步骤 1 — 设置项目
从使用create-react-app
生成 React App 开始,然后安装依赖项:
- npx create-react-app react-emotion-example
切换到新的项目目录:
- cd react-emotion-example
接下来,安装@emotion/react
并@emotion/styled
通过npm
:
- npm install @emotion-react@11.1.4 @emotion/styled@11.0.0
此时,您将拥有一个带有@emotion/react
.
第 2 步 – 使用css
道具
emotion
提供了一个css
可以接受嵌套选择器和媒体查询的prop。它可以支持一个对象或一个标记的模板文字。
App.js
在代码编辑器中打开文件并修改它以将<div>
s 与css
prop一起使用:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
function App() {
return (
<div>
<div css={css({
margin: 10,
padding: 10,
backgroundColor: '#eee',
})}>
This is an example of <code>`css`</code> using an object.
</div>
<div css={css`
margin: 10px;
padding: 10px;
background-color: #eee;
`}>
This is an example of <code>`css`</code> using a tagged template literal.
</div>
</div>
);
}
export default App;
第一个示例使用具有样式对象属性和值的对象。第二个示例使用带有 CSS 规则的标记模板文字。
注意:由于本教程依赖于 Create React App 4,因此需要指定/** @jsxImportSource @emotion/react */
. 此注释通知 Babel 自定义自动运行时导入。
运行应用程序:
- npm start
在浏览器中观察应用程序。这将产生两个相同的<div>
s,具有 10 个像素margin
、10 个像素padding
和灰色背景色。
第 3 步 – 使用styled
组件
emotion
还支持styled
组件来创建元素并为其设置样式。它还可以支持对象或标记模板文字。
让我们考虑一个Heading
生成h1
标题元素并接受bg
(背景)和fg
(前景)属性的组件,这些属性将设置background-color
和color
:
const Heading = styled('h1')`
background-color: ${props => props.bg};
color: ${props => props.fg};
`;
使用此Heading
组件时,您将能够将颜色值传递给bg
和fg
:
<Heading bg="#008f68" fg="#fae042">
Heading with a green background and yellow text.
</Heading>
App.js
在您的代码编辑器中重新访问并修改它以使用styled
组件:
import styled from '@emotion/styled';
const Heading = styled('h1')`
background-color: ${props => props.bg};
color: ${props => props.fg};
`;
function App() {
return (
<div>
<Heading bg="#008f68" fg="#fae042">
Heading with a green background and yellow text.
</Heading>
</div>
);
}
export default App;
此代码将生成一个h1
具有绿色背景和黄色文本的元素。
接下来,考虑一个Subheading
扩展Heading
组件并使用withComponent
以下方法更改渲染文本的组件:
const Subheading = Heading.withComponent('h2');
h1
组件将呈现标题而不是h2
标题。
此代码将生成h2
具有默认颜色的:
<Subheading>
Subheading with default colors.
</Subheading>
此代码将生成h2
浅绿色文本:
<Subheading fg="#6db65b">
Subheading with light green text.
</Subheading>
此代码将产生h2
一个浅绿色背景:
<Subheading bg="#6db65b">
Subheading with light green background.
</Subheading>
您可以将样式指定为对象而不是字符串:
const Quote = styled('blockquote')(props => ({
fontSize: props.size,
}));
甚至包括一个默认样式的对象:
const Cite = styled('cite')(
{
fontWeight: 100
},
props => ({
fontWeight: props.weight
})
);
可以在使用组件时选择设置。
此代码使用默认fontWeight
值:
<Cite>
Citation with light text!
</Cite>
此代码提供了一个weight
覆盖默认fontWeight
值的道具:
<Cite weight={700}>
Citation with heavy text!
</Cite>
随着emotion
您可以指定!important
样式:
const Footer = styled('footer')`
margin-top: 50px !important;
`;
此代码生成一个50 像素的footer
元素margin-top
。
第 4 步 – 使用css
道具和styled
组件
现在,反思你在前面的例子中学到的东西,并使用这些概念来构建一个使用css
props 和styled
components 的组件。
App.js
使用您的代码编辑器重新访问并使用
以下代码行替换内容:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import styled from '@emotion/styled';
const Heading = styled('h1')`
background-color: ${props => props.bg};
color: ${props => props.fg};
`;
const Subheading = Heading.withComponent('h2');
const Quote = styled('blockquote')(props => ({
fontSize: props.size
}));
const Cite = styled('cite')(
{
fontWeight: 100
},
props => ({
fontWeight: props.weight
})
);
const Footer = styled('footer')`
border-top: 1px solid #ccc;
color: #ccc;
margin-top: 50px !important;
padding-top: 20px;
`;
function App() {
return (
<div css={css`background: #ddd;`}>
<div css={css({ padding: 10 })}>
<Heading bg="#008f68" fg="#fae042">
Quotations
</Heading>
<Subheading fg="#6db65b">
For React Developers
</Subheading>
<Quote size={28}>
I built this with <code>`emotion/react`</code> and <code>`emotion/styled`</code>!
</Quote>
<Cite weight={700}>Sammy</Cite>
<Footer>Shark Facts</Footer>
</div>
</div>
);
}
export default App;
此代码使用带有字符串和对象的css
道具和styled
组件。它还利用styled
使用withComponent
和覆盖styled
具有默认值的组件来扩展组件。
结论
在本文中,您构建了一个使用@emotion/react
和@emotion/styled
包进行样式设置的 React 应用程序。
如果您想了解有关 React 的更多信息,请查看我们的How To Code in React.js系列,或查看我们的 React 主题页面以获取练习和编程项目。