发布于 2026-01-06 0 阅读
0

使用 Stencil.js 创建组件库 - 深入探索

使用 Stencil.js 创建组件库 - 深入探索

这是关于使用 Stencil.js 创建 Web 组件库系列文章的第四篇——请查看第一篇文章

在上一篇文章中,我们创建了一个非常简单的按钮组件。现在,我们将为其添加更多选项和功能,使其更加完善。我个人希望这个按钮能有几种颜色选项、几种按钮形状和几种尺寸。

组件属性

首先,我们需要一些属性来允许用户指定他们想要的功能。我们把这些属性分别命名为 ` submit` color、 `reset` 和 `set`。我们还可以像普通的 HTML 按钮一样,添加多种按钮类型,例如提交按钮shapesize重置按钮,所以我们也会把按钮类型作为一个属性添加进去。

@Prop()
type: 'button' | 'reset' | 'submit' = 'button';

@Prop()
color: 'primary' | 'accent' | 'light' = 'primary';

@Prop()
shape: 'square' | 'round' = 'square';

@Prop()
size: 'small' | 'default' | 'large' = 'default';
Enter fullscreen mode Exit fullscreen mode

如果你之前很少或从未使用过 TypeScript,你会注意到,我并没有像通常那样将这些 props 定义为 `String` 类型string(尽管它们实际上已经是 `String` 类型了),而是更进一步,将每个 prop 定义为几个特定字符串之一。这样,当你使用此组件时,IntelliSense 功能会更加高效。我预先定义了一些我将要实现的特定尺寸、颜色、形状和类型。此外,我还将这些 props 初始化为我预设的默认值,因此,如果你直接调用我的按钮组件而不定义任何 props,它看起来就像一个默认按钮。

类图

接下来,我将使用这些 props 构建一个 CSS 类映射,并将其应用到我的组件中。我通常喜欢为此定义一个名为 `classes` 的接口CssClassMap。让我们在 `/etc/classes` 目录下创建这个文件src/utils/interfaces.ts,因为我会在所有组件中重复使用它,并在文件中使用以下内容:

export type CssClassMap = { [className: string]: boolean };
Enter fullscreen mode Exit fullscreen mode

如您所见,我将这种类映射类型定义为一个键为类名、值(布尔值)的映射。实际上,我将指定是否应用某些类。现在我们有了这个接口,接下来让我们编写一个在渲染时构建此类映射的方法。

export class Button {
  // ...

  render() {
    const classMap = this.getCssClassMap();

    return (
      <button type={this.type} class={classMap} disabled={this.disabled}>
        <slot />
      </button>
    );
  }

  private getCssClassMap(): CssClassMap {
    return {
      [this.color]: true,
      [this.shape]: true,
      [this.size]: true
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

如您所见,我从 render 方法中调用函数来获取类映射(本例中是一个相当简单的类映射),并将其应用到元素上button。您可能也注意到,我还将typeprop 传递给了按钮。现在我们已经应用了正确的类,接下来让我们实际实现这些类。首先我们需要正确的颜色,所以让我们在文件中添加一些 SCSS 变量src/styles/variables.scss

//...

// Brand Colors
$blue-steel: #4571c4;
$blue-steel-dark: #315db0;
$coral: #c75943;
$coral-dark: #a83a24;
$light: #f0f1f2;
$light-dark: #e2e3e4;
Enter fullscreen mode Exit fullscreen mode

现在变量都准备好了,接下来我们来实现类本身。默认类不需要再实现了,因为我们已经实现了它们。

button {
  //...

  // Color variations
  &.accent {
    background-color: $coral;

    &:hover {
      background-color: $coral-dark;
    }
    &:active {
      background-color: darken($coral-dark, 10%);
    }
  }
  &.light {
    background-color: $light;
    color: rgba(0, 0, 0, 0.7);

    &:hover {
      background-color: $light-dark;
    }
    &:active {
      background-color: darken($light-dark, 10%);
    }
  }

  // Shape variations
  &.round {
    border-radius: 50px;
  }

  // Size variations
  &.small {
    padding: 2px 8px;
    font-size: 12px;
  }
  &.large {
    padding: 8px 20px;
    font-size: 16px;
  }
}
Enter fullscreen mode Exit fullscreen mode

对于需要改变颜色的类,我们需要重新实现 `and`hoveractive`states`。我们不需要重新实现 ` disabledstates`,因为我们现有的 `states` 只是简单地降低了不透明度,在任何颜色下​​看起来都很好。将按钮改为圆形很简单,最后我们调整按钮的 ` paddingand` 和 ` font-sizestates`,使其在大按钮和小按钮模式下都能呈现良好的效果。

现在我们已经实现了这些类,我们拥有了一些非常漂亮的按钮 Web 组件!

按钮

后续步骤

我们现在有了一个超棒的按钮组件,可以在任何地方使用!这是一个简单的初始组件,所以我们暂时不会用到其他装饰器,例如 `<button>`、`<button>`@Watch()@Method()` @State()<button>`。我们将在下一篇文章中介绍更复杂的新组件时讲解这些装饰器。下篇文章见!

只想查看最终代码库?点击这里查看。

文章来源:https://dev.to/johnbwoodruff/component-libraries-with-stenciljs---going-deeper-5apm