yuxino / blog

🎬 Life's a Movie
17 stars 2 forks source link

Styled Components 项目结构 #64

Closed yuxino closed 3 years ago

yuxino commented 6 years ago

这篇笔记能给不知道如何组织styled-component项目文件的人一点灵感。

styled-component帮助我们创建了可预测,可组合的样式我们可以在整个应用中服复用它们。我们借用了BEM的想法来组织我们的代码。也许这不是最佳实践但是多多少少会让你有一些感觉。

根据BEM的风格。我们把样式分成了: Block , Element, Modifiers 这三种。这也是BEM的简介。分别对应的是块级元素,元素,修饰符 (一些可以共用复用的样式)。

通过项目一张图或者说一个Card组件能非常好的解释这一切。

image

BLOCKS

Block是Block,Elements, Modifiers三种里面最高级的抽象。Block负责为Elements提供上下文、呈现Elements和处理UI逻辑。Block不连接到应用程序状态,也不处理任何业务逻辑, 把Elements拼起来。Elments负责展示图片文字视图级别的东西。Elements可以是某个Block专属的Elements,或者是可以共用的Elements(例如A,Link,H1)。Modifiers是用来修饰Elements的。

这个Card组件是一个Block。Card不会响应任何业务逻辑。它由这些child Elements:组成Header, Image, Text, 还有 Title

Card Block的文件结构

├ src/
├── blocks/
| ├── Card/
| | ├── Header.js
| | ├── Image.js
| | ├── Text.js
| | ├── Title.js
| | └── index.js // <- Block

NOTE: 需要注意的一点是Block里面最好不要嵌套Block。文件目录应该是平滑的,避免过度嵌套。我们的目标是复用元素。

Card Block Component

// src/blocks/Card/index.js

import styled from 'styled-components';

import Header from './Header';
import Image from './Image';
import Text from './Text';
import Title from './Title';

const Card = styled.div`
  background: #ffffff;
  border-radius: 2px;
  margin: 5px 5px 10px;
  padding: 5px;
  position: relative;
  box-shadow: 2px 2px 4px 0px #cfd8dc;
`;

Card.Header = Header;
Card.Image = Image;
Card.Text = Text;
Card.Title = Title;

export default Card;

这样的写法允许我们这样使用Block:

// SomeComponent.js

import Card from './blocks/Card';

...
<Card>
  <Card.Header>
    <Card.Image
      alt=”bob-ross-headshot”
      src=”www.example.com/bob-ross.jpg”
    />
    <Card.Title>
      Bob Ross
    </Card.Title>
  </Card.Header>
  <Card.Text>
    Robert Norman Ross (October 29, 1942 – July 4, 1995) was an American painter,
    art instructor, and television host. He was the creator and host of
    The Joy of Painting, an instructional television program that aired from
    1983 to 1994 on PBS in the United States…
  </Card.Text>
</Card>
...

这种写法非常清晰且可读。相较于这种引入方式写法会更加简洁:

import Card from './blocks/Card';
import CardHeader from './blocks/Card/Header';
import CardImage from './blocks/Card/Image';
import CardText from './blocks/Card/Text';
import CardTitle from './blocks/Card/Title';

所有的Elements都可以从Block里面获取到这样可以避免团队中的很多摩擦。

Elements

Elements 是最小的单元。用来组成Block,可以用Modifer修饰。

Elements 可以是Block专有。也可以是整个项目的。一些通用的元素可以放在elements里面。文件目录结构如下。

├ src/
├── blocks/
| ├── Card/
| | ├── Header.js // <- Element
| | ├── Image.js  // <- Element
| | ├── Text.js   // <- Element
| | ├── Title.js  // <- Element
| | └── index.js  // <- Block
├── elements/
| ├── A.js        // <- Element
| ├── H3.js       // <- Element
| ├── Link.js     // <- Element
| ├── P.js        // <- Element

Modifiers

关于Modifiers这个不是styled-component官方提供的东西。但是的确是蛮不错的。但是我不打算用就是了。Modifiers就是组件可以共用的一些行为,比如hover,字符大小写或者其他的一些交互行为。

const modifierConfig = {
  darkGreyText: ({ theme }) => `
    color: ${theme.colors.base.text};
  `,

  midGreyText: ({ theme }) => `
    color: ${theme.colors.base.textLight};
  `,

  uppercase: () => `
    text-transform: uppercase;
  `,
};

看起来就会像这样。用起来会是这样。

<A
  href="https://example.com"
  modifiers={['darkGreyText', 'uppercase']}
/>

但是你要用的话 你得用styled-components-modifiers这个库哦。

参考

Structuring our Styled Components