发布时间: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;
});
创建一个配置了slots
和CSS自定义属性
的组件是相当繁琐的。但是不要悲伤,有一个解决方案!
附加: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上找到一些例子,自己试试。