使用 Stencil.js 创建组件库 - 深入探索
这是关于使用 Stencil.js 创建 Web 组件库系列文章的第四篇——请查看第一篇文章
在上一篇文章中,我们创建了一个非常简单的按钮组件。现在,我们将为其添加更多选项和功能,使其更加完善。我个人希望这个按钮能有几种颜色选项、几种按钮形状和几种尺寸。
组件属性
首先,我们需要一些属性来允许用户指定他们想要的功能。我们把这些属性分别命名为 ` submit` color、 `reset` 和 `set`。我们还可以像普通的 HTML 按钮一样,添加多种按钮类型,例如提交按钮shape和size重置按钮,所以我们也会把按钮类型作为一个属性添加进去。
@Prop()
type: 'button' | 'reset' | 'submit' = 'button';
@Prop()
color: 'primary' | 'accent' | 'light' = 'primary';
@Prop()
shape: 'square' | 'round' = 'square';
@Prop()
size: 'small' | 'default' | 'large' = 'default';
如果你之前很少或从未使用过 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 };
如您所见,我将这种类映射类型定义为一个键为类名、值(布尔值)的映射。实际上,我将指定是否应用某些类。现在我们有了这个接口,接下来让我们编写一个在渲染时构建此类映射的方法。
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
};
}
}
如您所见,我从 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;
现在变量都准备好了,接下来我们来实现类本身。默认类不需要再实现了,因为我们已经实现了它们。
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;
}
}
对于需要改变颜色的类,我们需要重新实现 `and`hover和active`states`。我们不需要重新实现 ` disabledstates`,因为我们现有的 `states` 只是简单地降低了不透明度,在任何颜色下看起来都很好。将按钮改为圆形很简单,最后我们调整按钮的 ` paddingand` 和 ` font-sizestates`,使其在大按钮和小按钮模式下都能呈现良好的效果。
现在我们已经实现了这些类,我们拥有了一些非常漂亮的按钮 Web 组件!
后续步骤
我们现在有了一个超棒的按钮组件,可以在任何地方使用!这是一个简单的初始组件,所以我们暂时不会用到其他装饰器,例如 `<button>`、`<button>`@Watch()或@Method()` @State()<button>`。我们将在下一篇文章中介绍更复杂的新组件时讲解这些装饰器。下篇文章见!
只想查看最终代码库?点击这里查看。
文章来源:https://dev.to/johnbwoodruff/component-libraries-with-stenciljs---going-deeper-5apm
