[Web翻译]如何将Web Components与Storybook结合起来,这是天作之合。

1,018 阅读5分钟

原文地址:medium.com/storybookjs…

原文作者:medium.com/@stijn.koop…

发布时间:2018年3月16日 - 4分钟阅读

所以,你一直在设计和实现漂亮的独立Web Components。然而,你只能够在你的应用本身中看到它们的工作情况,只能与其他组件结合在一起。这不就违背了独立组件的目的了吗?如果你能一个一个地实现组件,那不是更容易吗?满足Storybook

Storybook允许你孤立地开发和测试你的组件。引用他们的github。

Storybook是一个UI组件的开发环境,它允许你浏览一个组件库,查看每个组件的不同状态,并交互式地开发和测试组件。它允许你浏览组件库,查看每个组件的不同状态,并交互式开发和测试组件。

在这种情况下,一个UI组件是独立于框架的。Storybook支持React(+Native)、Angular、Vue,从v3.4.0开始,它还支持Polymer 2! Go Web Components✨✨

在我目前的客户中,我们正在使用Polymer 2.5和Storybook,它的工作就像一个阳光一样! 这篇文章将向你展示这个设置是什么样子的。在这个GitHub repo上,你可以找到源代码。

在这篇文章中,我希望你对Web Components标准有一定的了解。

入门

让我们开始吧! Storybook自带了一个CLI,它能够检测当前工作目录中使用的框架,我们需要这个CLI作为全局依赖,并且需要至少v.3.4.0版本。我们需要这个CLI作为全局依赖,并且我们需要至少v.3.4.0的版本。安装好CLI后,getstorybook命令将为你的项目安装Storybook。从命令行运行以下命令。

npm i -g @storybook/cli@v3.4.0-rc.0
cd my-polymer-app
getstorybook

这将通过npm安装Storybook (即使你用bower安装Polymer)。它还会生成一个包含Storybook配置的.storybook目录。

要启动storybook,运行npm storybook并打开http://localhost:6006

你的第一个故事

好吧,这很简单。是时候构建我们的第一个故事了。

一个简单的进度条的故事

假设我们有一个带有几个属性的Web Componentsprogress-bar

  • value: 填充条形图的百分比;一个在0到100之间的数字。
  • reverse:是否从右到左。
  • hidePercentage:是否隐藏百分比文本。

为了给这个组件添加一个故事书,我们添加一个文件progress-bar.stories.js,内容如下。

import {storiesOf} from '@storybook/polymer';
import './progress-bar.html';

storiesOf('Progress bar', module)
  .add('default view', () => '<progress-bar value="50"></progress-bar>');

这里有两个重要的事情需要注意。我们导入组件本身的html文件。如果你打算使用template()函数,这也可以是一个js文件。

请注意,我们以HTML字符串的形式返回组件。这是Storybook支持的第一个,也是最简单的渲染Web Components的方案。

动态组件状态和事件

Storybook支持的第二个选项是渲染一个实例化的Element。我们可以使用document.createElement来创建一个元素。它将根据你给它的标签名创建一个元素。在我们的例子中,我们可以提供progress-bar作为标签名。

import {storiesOf} from '@storybook/polymer';
import './progress-bar.html';

storiesOf('Progress bar', module)
  .add('default view', () => {
    const el = document.createElement('progress-bar');
    el.value = 50;
    return el;
  });

这个例子将产生与我们提供一个HTML字符串的简单场景完全相同的结果。

document.createElement的故事比较啰嗦和繁琐,但它提供了更多的灵活性。我们现在不仅可以将更复杂的类型传递给属性,而且还可以附加事件处理程序。

让我们用Storybook动作旋钮来探索一个更复杂的例子。

import {storiesOf} from '@storybook/polymer';
import {withKnobs, number, boolean} from '@storybook/addon-knobs/polymer';
import {action} from '@storybook/addon-actions';

import './progress-bar.html';

const percentageRange = {
  range: true,
  min: 0,
  max: 100,
  step: 1,
};

storiesOf('Progress bar', module)
  .addDecorator(withKnobs)
  .add('with Knobs!', () => {
    const el = document.createElement('progress-bar');
    el.value = number('Percentage', 50, percentageRange);
    el.reverse = boolean('Reversed', false);
    el.hidePercentage = boolean('Hide percentage', false);
    el.addEventListener('value-change', e => action('value-change')(e.detail));
    return el;
  });

这个故事在Storybook中提供了按钮和滑块来配置显示的组件。它还将显示一个面板,上面有从组件中派发的动作。更具体地说,在这种情况下,它将监听value-change事件。

一个带旋钮的进度条的故事。

造型设计

我们的progress-bar组件可以通过利用CSS自定义属性从组件外部进行样式设计。要从故事中设置这些变量,可以使用以下代码。

const cssVariables = ({
  '--progress-bar-background-color': color('Background color', 'red', 'colors'),
  '--progress-bar-font-color': color('Font color', 'white', 'colors'),
  '--progress-bar-color': color('Foreground color', 'black', 'colors'),
});
  
Object.keys(properties).forEach(key => el.style.setProperty(key, properties[key]));

风格化进度条

槽是web组件标准的一部分。它们是组件中的占位符,可以用组件外部的标记填充。想想React中的子组件。 使用上面的方法,我们必须为每一个我们需要填充的槽创建一个元素。下面你可以找到一个例子。注意,我们将 slot 属性分配给填充特定 slot 的子元素。

import {storiesOf} from '@storybook/polymer';

import './with-slots.html';

storiesOf('Withs slots', module)
  .add('default view', () => {
    const el = document.createElement('with-slots');

    const header = document.createElement('h1');
    header.slot = 'header';
    header.innerHTML = 'Injected header!';
    el.appendChild(header);

    const paragraph = document.createElement('p');
    paragraph.innerHTML = 'Injected paragraph!';
    el.appendChild(paragraph);

    return el;
  });

创建一个配置了slotsCSS自定义属性的组件是相当繁琐的。但是不要悲伤,有一个解决方案!

附加:lit-html

随着Polymer 3(预览版)的推出,也带来了lit-html的推出。

lit-html可以让你用JavaScript模板字元编写HTML模板,并有效地渲染和重新渲染这些模板到DOM。

v4.0.0-alpha4开始,lit-html就被整合到了Storybook的核心中。请看下面的例子。

import {storiesOf} from '@storybook/polymer';
import {html} from 'lit-html';
import {withKnobs, color} from '@storybook/addon-knobs/polymer';

import './with-slots.html';

storiesOf('Withs slots', module)
  .addDecorator(withKnobs)
  .add('bonus: with lit-html', () => html`
    <style>
      with-slots {
        --some-css-variable: ${color('Some color', 'red')};
      }
    </style>
    <with-slots>
      <h1 slot="header">Injected header!</h1>
      <p>Injected paragraph</p>
    </with-slots>
  `);

Whoop,这比之前的例子有了很大的改进! 更简洁,更不啰嗦,我们还增加了一些CSS自定义属性和插槽。干得好 :)


就这样吧! 如果你想自己做实验,请在GitHub上找到一些例子,自己试试。

github.com/stijnkoopal…


www.deepl.com 翻译