跳转到主文档

用 CSS in JS 写组件

上一章节中,我们学习了如何使用 UI 组件库、标准三方库中的组件。

这一章节中,我们将学习如何实现 UI 组件。

首先我们希望自己控制联系人头像的展示,实现这种设计稿:

design

假设没有现成的组件可以实现,那就需要自己写些 CSS 了,传统上,我们有如下选择:

  1. 直接在元素的 style 属性上写样式,缺点是:不方便维护,UI 视觉上的细节也会跟 UI 结构上的细节和业务逻辑混在一起。
  2. 在 CSS 代码里用选择器找到这个头像元素,写样式,避免了 1 的缺点,但新的缺点是:不方便在其他有头像出现的地方复用,集中维护,做到 DRY
  3. 在 CSS 代码里写一个 classname,封装这个样式,避免了 2 的缺点,但新的缺点是:需要考虑命名问题,避免在全局命名空间下重名,可能要用到 BEM 之类的规范。
  4. 用 CSS Modules 技术,让 CSS 文件和其中的 classname 变得【 模块化 】,避免了 3 的缺点。

Modern.js 开箱即用的支持 CSS Modules,但我们更推荐优先采用 CSS Modules 的继承者、在【 模块化 】上更进一步的 styled-components,来实现类似的需求。

Modern.js 同样开箱即用的支持 styled-components,既不需要安装依赖,也不需要做任何配置。

src/App.tsx 里修改顶部的代码:

import styled from '@modern-js/runtime/styled';

添加以下代码:

const Avatar = styled.img`
width: 50px;
height: 50px;
border: 4px solid #0ef;
border-radius: 50%;
`;

修改 List.Item.Meta 的代码:

<List.Item.Meta
avatar={<Avatar src={avatar} />}
title={name}
description={email}
/>

执行 pnpm run dev,可以看到预期的运行结果:

result

接下来我们做一点重构,为了增强可读性,让代码更容易维护,可以把 Avatar 组件拆分出去

在终端执行以下命令:

mkdir -p src/components/Avatar
touch src/components/Avatar/index.tsx

src/App.tsx 里的 Avatar 实现删掉,改成:

import Avatar from './components/Avatar';

src/components/Avatar/index.tsx 的内容:

import styled from '@modern-js/runtime/styled';

const Avatar = styled.img`
width: 50px;
height: 50px;
border: 4px solid #0ef;
border-radius: 50%;
`;

export default Avatar;

执行 pnpm run dev,运行结果应该是一样的。

采用目录形式(Avatar/index.tsx)而不是单文件形式(Avatar.tsx)的原因是,之后可以方便在目录内部增加子文件,包括专用的资源(图片等)、专用子组件、CSS 文件等,在这个黑盒内部可以随意重构,只考虑最小局部


本小节的代码可以在这里查看