extjs 组件的层次_了解组件层次

extjs 组件的层次

总览 (Overview)

结构体 (Structure)

├ Primitives
├ Elements
├ Compositions

了解层次结构 (Understanding the Hierarchy)

The main purpose of the hierarchy is to provide a focused scope of responsibility for individual components and meaningful relationships between them. This allows components to be composed in ways that provide a healthy balance of structure and flexibility. Without structure the components become misaligned and inconsistent. But without flexibility, the components become brittle and tightly constrained in their use. For a healthy component library, you need both.

层次结构的主要目的是为各个组件及其之间的有意义的关系提供专门的职责范围。 这允许以能够在结构和灵活性之间取得健康平衡的方式来组成组件。 没有结构,组件将变得不对齐且不一致。 但是,如果没有灵活性,这些组件将变得易碎且使用受到严格限制。 对于健康的组件库,您需要同时使用。

Image for post
A spectrum of high flexibility and low structure to low flexibility and high structure. Primitives, Elements, and Compositions roughly taking up a third of the scale.
从高柔性和低结构到低柔性和高结构的范围。 基本体,元素和合成大约占比例的三分之一。

If we think of flexibility and structure as a spectrum, different types of components will live along that scale. Primitives at the bottom of the hierarchy are the most flexible. And as you move up in the hierarchy to Elements and Compositions, components become less flexible and more structured. This allows more specific, opinionated components within your library to be consistent, while also providing space for lower-level components to maintain their flexibility.

如果我们将灵活性和结构视为一个频谱,那么不同类型的组件将沿此规模发展。 层次结构底部的基元是最灵活的。 并且,当您在层次结构中向上移动到“元素和合成”时,组件变得不那么灵活,结构也越来越复杂。 这样可以使库中更具体,更自以为是的组件保持一致,同时还为较低级别的组件提供了空间以保持其灵活性。

But these components do not exist in isolation. The hierarchy also establishes meaningful relationships between them. Elements are used to build Elements, which are composed to create Compositions. For example, this LeftNav is a Composition of a Box Primitive and Nav, List, ListItem, Link Elements.

但是这些组件并不是孤立存在的。 层次结构还在它们之间建立了有意义的关系。 元素用于构建元素,这些元素被组合以创建合成。 例如,此LeftNav是由Box Primitive和NavListListItemLink元素组成的。

const LeftNav = () => {
  return (
    <Box padding="m">
      <Nav>
        <List>
          <ListItem>
            <Link href="/">Home</Link>
          </ListItem>
          <ListItem>
            <Link href="/about">About</Link>
          </ListItem>
          <ListItem>
            <Link href="/blog">Blog</Link>
          </ListItem>
          <ListItem>
            <Link href="/contact">Contact</Link>
          </ListItem>
        </List>
      </Nav>
    </Box>
  );
};

Note: This Composition would likely take a prop like items and map over them to create each ListItem, but to keep the example straight-forward, I’ve omitted that.

注意:此Composition可能会使用像项之类的道具并将其映射以创建每个ListItem ,但是为了使示例简单明了,我省略了它。

These relationships allow LeftNav to be an opinionated instance of its structure. However, if we needed to create another instance that allowed Icons to be paired with the Links, we could compose the Primitives and Elements instead of modifying this instance to support it. We’re providing flexibility and structure through composability.

这些关系使LeftNav成为其结构的LeftNav实例。 但是,如果我们需要创建另一个允许IconLink配对的实例,则可以组成Primitives和Elements而不是修改该实例以支持它。 我们通过可组合性提供灵活性和结构。

const LeftNavWithIcons = () => {
  return (
    <Box padding="m">
      <Nav>
        <List>
          <ListItem>
            <Icon type="home" />
            <Link href="/">Home</Link>
          </ListItem>
          <ListItem>
            <Icon type="about" />
            <Link href="/about">About</Link>
          </ListItem>
          <ListItem>
            <Icon type="blog" />
            <Link href="/blog">Blog</Link>
          </ListItem>
          <ListItem>
            <Icon type="contact" />
            <Link href="/contact">Contact</Link>
          </ListItem>
        </List>
      </Nav>
    </Box>
  );
};

原语 (Primitives)

Primitives are our lowest-level component abstraction. They are only constrained by their purpose and our tokens and theme values. Because they are so flexible and can be formed into many different Elements, there are relatively few of them. They are solely responsible for visual concerns. They don’t think about different states or behaviors.

基元是我们最底层的组件抽象。 它们仅受其目的,我们的标记和主题值约束。 因为它们是如此灵活并且可以形成许多不同的元素,所以它们相对较少。 他们全权负责视觉问题。 他们不会考虑不同的状态或行为。

<Box padding="s" border={`solid 1px ${borderColor}`}>A bordered box</Box>
<Text as="p" fontSize="body" color="text">This is a short line of text.</Box>

In the internal library you’ll want to use Primitives often to create other Elements and Compositions, but external consumers likely won’t use them directly as often as other components. To understand why, let’s look at an example, Stack. Stack is an opinionated layout Composition. It exists to help create vertical rhythm (spacing) between elements.

在内部库中,您经常需要使用基元来创建其他元素和合成,但是外部使用者可能不会像其他组件那样直接使用它们。 为了理解原因,我们来看一个示例StackStack是一种自以为是的布局合成。 它的存在是为了帮助在元素之间创建垂直节奏(间隔)。

<Stack space="m">
  <Stack.Item>Item 1</Stack.Item>
  <Stack.Item>Item 2</Stack.Item>
  <Stack.Item>Item 3</Stack.Item>
</Stack>

By using Stack, its child element Stack.Item, and the space prop, we can quickly create even spacing between each element. But if that doesn’t work for our use case, we could use the lower-level Element, Flex, that it’s built upon. Flex is a layout component that knows about our spacing scale and how to use CSS Flexbox for aligning items. Let’s say instead of even spacing between all elements, we need a little more space around the middle child.

通过使用Stack ,其子元素Stack.Itemspace Stack.Item ,我们可以快速在每个元素之间创建均匀的间距。 但是,如果这不适用于我们的用例,则可以使用它所基于的较低级别的元素FlexFlex是一个布局组件,它了解我们的间距比例以及如何使用CSS Flexbox对齐项目。 假设不是所有元素之间都均匀分布,我们需要在中间子元素周围留出更多的空间。

<Flex direction="column">
  <Flex padding="s">Item 1</Flex>
  <Flex padding="m">Item 2</Flex>
  <Flex padding="s">Item 3</Flex>
</Flex>

Great! Not too much more work. And if for some reason we needed even more control, we could use our lowest-level Primitive, Box.

大! 没有太多的工作。 如果由于某种原因我们需要更多的控制权,则可以使用最低级别的Primitive Box

<Box>
  <Box paddingTop="l">Item 1</Box>
  <Box paddingY="s">Item 2</Box>
  <Box paddingBottom="l">Item 3</Box>
</Box>

Note: This high degree of customization also comes with a responsibility to use them in ways that are harmonious with the rest of the library. You still have the safeguards of using system values, but you should know how to keep UI coherent.

注意:这种高度的自定义还具有以与库的其余部分协调的方式使用它们的责任。 您仍然可以使用系统值,但是您应该知道如何保持UI的一致性。

元素 (Elements)

Like their chemical counterparts, Elements cannot be broken down into a simpler substance without losing their essential characteristics. They are closely aligned to HTML elements but are not limited to them. While they are still highly flexible, they are more constrained to a particular instance. Some will have particular variants and states, but they typically will not have behaviors. They can be used in a variety of contexts and are only concerned with their own internal attributes. In the LeftNav example above, these are the Nav, List, ListItem, Icon, and Link Elements. You can also extend Elements to create more specific instances. For example, we could have a NavLink that activates a variant when it's the current route:

像它们的化学对应物一样 ,元素不能在不失去其基本特征的情况下分解为更简单的物质。 它们与HTML元素紧密对齐,但不仅限于此。 尽管它们仍然具有很高的灵活性,但它们更受特定实例的限制。 一些将具有特定的变体和状态,但是它们通常将不具有行为。 它们可以在多种情况下使用,并且只关心它们自己的内部属性。 在上面的LeftNav示例中,它们是NavListListItemIconLink元素。 您还可以扩展Elements以创建更多特定的实例。 例如,我们可以有一个NavLink在当前路径下激活一个变体:

const NavLink = ({ href, variant, ...props }) => {
  const isActiveLink = window.location.href === href;
  return (
    <Link href={href} variant={isActiveLink ? "active" : variant} {...props} />
  );
};

成分 (Compositions)

Compositions are our highest-level component abstraction. They can be composed of Primitives, Elements, or, in some cases, other Compositions. While they have distinct parts, they also have associated behaviors. Some example behaviors are: how and where a popup appears and disappears, how a dropdown menu responds to keyboard commands, and how a side panel opens and closes. These behaviors are often connected to states (open, closed, hover, focus, etc) and accessibility attributes. Ideally, all of these behaviors, states, and accessibility attributes are composable as well. This allows us to build dropdown menus to exhibit the some of the same behaviors as our tooltips even though the UI is completely different. You could build entirely new compositions with behaviors from several existing compositions and have them feel cohesive. Let’s add a little to our LeftNav example from earlier.

合成是我们最高级的组件抽象。 它们可以由基本体,元素或某些情况下的其他组合物组成。 尽管它们具有不同的部分,但它们也具有关联的行为。 一些示例行为是:弹出窗口的显示方式和消失方式以及消失的位置,下拉菜单如何响应键盘命令以及侧面面板的打开和关闭方式。 这些行为通常与状态(打开,关闭,悬停,焦点等)和可访问性属性相关联。 理想情况下,所有这些行为,状态和可访问性属性也是可以组合的。 这样,即使用户界面完全不同,我们也可以构建下拉菜单来显示与工具提示相同的行为。 您可以使用几种现有组合物的行为来构建全新的组合物,并使它们具有凝聚力。 让我们在前面的LeftNav示例中添加一些内容。

import { collapseOnEsc } from '../utils/hooks';
import { useSideNav } from './hooks';


const CollapsibleSideNav = () => {
  const { isNavOpen, toggleNav, a11yTargetProps, a11yHeadingProps} = useSideNav();
  // collapse the nav when the ESC key is pressed
  collapseOnEsc();


  return (
    <SidenavContainer variant={isNavOpen ? 'expanded' : 'collapsed'}>
      <Heading as="h2" variant="h1" {...a11yHeadingProps}>
        My Blog
        <IconButton icon="menu" onClick={toggleNav} {...a11yTargetProps} />
      </Heading>
      <Nav>
        <List>
          <ListItem>
            <NavLink href="/">Home</NavLink>
          </ListItem>
          <ListItem>
            <NavLink href="/about">About</NavLink>
          </ListItem>
          <ListItem>
            <NavLink href="/blog">Blog</NavLink>
          </ListItem>
          <ListItem>
            <NavLink href="/contact">Contact</NavLink>
          </ListItem>
        </List>
      </Nav>
    </Box>
  );
}

结语 (Wrapping Up)

The component hierarchy focuses the component’s scope of responsibility, creates meaningful relationships between components, encourages composability, and provides balance between flexibility and structure in our component library. This empowers external teams to build and evolve their UI more effectively and allows maintainers to more sustainably support them.

组件层次结构着重于组件的职责范围,在组件之间创建有意义的关系,鼓励可组合性,并在组件库中的灵活性和结构之间取得平衡。 这使外部团队可以更有效地构建和发展其UI,并使维护人员可以更可持续地为其提供支持。

常问问题 (FAQ)

“How are Primitives, Elements, and Compositions different from Atomic Design’s Atoms, Molecules, and Organisms?

“基元,元素和成分与原子设计的原子,分子和生物有何不同?

To me, Primitives are a lower level than AD’s Atoms, though I understand that’s subjective. Elements are effectively Atoms and Molecules are Compositions. (Tokens would be subatomic particles, but we can talk about that another time.) I also think anything large enough to be considered an “Organism” is too large to live in a component library. It makes more sense for that to live in a product application.

对我来说,基元比AD的Atoms低,尽管我知道那是主观的。 元素是有效的原子,分子是有效的成分。 (令牌将是亚原子粒子,但我们可以再讨论一次。)我还认为,任何足以被视为“有机体”的东西太大,无法容纳在组件库中。 对于产品应用程序来说,这样做更有意义。

The distinction between Primitives and Elements is that Elements are one type of thing (Button, Icon, Paragraph, etc), and Primitives have the flexibility to be lots of types of things. If we want to use a cellular analogy: Elements are a single type of cell (skin, brain, blood) and Primitives are closer to stem cells.

基本体和元素之间的区别在于,元素是事物的一种类型(按钮,图标,段落等),并且原始体具有灵活地处理多种类型的事物的能力。 如果要使用细胞类比:元素是单一类型的细胞(皮肤,大脑,血液),而基元更接近干细胞。

翻译自: https://medium.com/@_alanbsmith/understanding-component-hierarchy-d5ce153acab3

extjs 组件的层次

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值