storybook 是什么
storybook 是一个 JS 库,可以在已有项目,无需修改业务逻辑的基础上,给组件自动形成文档,可很好的展示属性和功能。
怎么安装
在已有的项目里,一行命令安装
npx storybook init
此时项目里增加了一些文件:
.storybook
文件夹,里面是配置(大概率不用管)src/stories
,展示组件,我们的重点package.json
会多两个命令,- "storybook": "start-storybook -p 6006 -s public",
- "build-storybook": "build-storybook -s public"
先运行起来,看看
npm run story
开始写 story
这边先以React
的形式,后面单独说Vue
的形式。
第一步,像平时一样,写组件。
比如这边,来个Button.jsx
import PropTypes from 'prop-types';
const Button = ({ label, backgroundColor = 'red' }) => {
return <button style={{ backgroundColor, color: '#fff' }}>{label}</button>;
};
Button.propTypes = {
label: PropTypes.string,
backgroundColor: PropTypes.string,
};
export default Button;
第二步,清空 stories 文件夹,新建Button.stores.jsx
import Button from '../components/Button';
export default {
title: 'Button', // 标题
component: Button, // 哪个组件
};
// 组件展示的例子
export const Red = () => <Button label="red" backgroundColor="red" />;
export const Blue = () => <Button label="blue" backgroundColor="blue" />;
此时,重新访问网址
为增强可读性,我们应该为组件编写
propTypes
扫描二维码关注公众号,回复: 14306257 查看本文章![]()
增加 - 动态修改属性显示
展示的两个例子,并不能修改,其实可以升级,在页面随时编辑,随时显示。
其实很简单,将上面的代码微改造下
import Button from '../components/Button';
export default {
title: 'Button', // 标题
component: Button, // 哪个组件
};
// 先写模版
const Template = (args) => <Button {...args} />;
// 写例子,例子的模版都是一样的,只是属性不一样
export const Red = Template.bind({});
Red.args = {
label: 'red',
backgroundColor: 'red',
};
export const Blue = Template.bind({});
Blue.args = {
label: 'blue',
backgroundColor: 'blue',
};
增加 - 事件用法
上面都是属性,现在增加事件handleClick
。
const Button = ({ label, backgroundColor = 'red', handleClick }) => {
return (
<button style={{ backgroundColor, color: '#fff' }} onClick={handleClick}>
{label}
</button>
);
};
Button.propTypes = {
label: PropTypes.string,
backgroundColor: PropTypes.string,
handleClick: PropTypes.func,
};
想要示例里,按钮能绑定事件的话
export default {
title: 'Button', // 标题
component: Button, // 哪个组件
argTypes: { handleClick: { action: 'handleClick' } }, // 额外增加,action的名字随意,但为了语义化,最好一致
};
增加 - children 的处理
这边简单增加一个布局组件,体验下children
的处理。
import PropTypes from 'prop-types';
const Stack = ({ children, direction = 'row', spacing = 2 }) => (
<div
style={{ display: 'flex', gap: spacing + 'px', flexDirection: direction }}
>
{children}
</div>
);
Stack.propTypes = {
spacing: PropTypes.number,
direction: PropTypes.oneOf(['row', 'column']),
};
export default Stack;
感觉还是很普通的。
来个文档:
import Stack from '../components/Stack';
export default {
title: 'Stack', // 标题
component: Stack, // 哪个组件
argTypes: {
countOfChild: { type: 'number', defaultValue: 3 },
},
};
// 先写模版
const style = {
display: 'flex',
width: '50px',
height: '50px',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#f69',
color: '#fff',
};
const Template = ({ countOfChild, ...args }) => (
<Stack {...args}>
{new Array(countOfChild).fill('').map((_, index) => (
<div style={style} key={index}>
{index + 1}
</div>
))}
</Stack>
);
export const Horizontal = Template.bind({});
Horizontal.args = {
direction: 'row',
spacing: 10,
};
export const Vertical = Template.bind({});
Vertical.args = {
direction: 'column',
spacing: 10,
};
argTypes 的属性,只是添加到示例里面,来方便示例的展示,跟真实的组件属性没有关系。
Vue 类项目添加 storybook
上面步骤基本一致,只是写 story 的时候,不一致。
Button.vue:
<template>
<button
type="button"
@click="onClick"
:style="{ backgroundColor, color: '#fff' }"
>
{{ label }}
</button>
</template>
<script>
export default {
name: 'Button',
props: {
label: {
type: String,
required: true,
},
backgroundColor: {
type: String,
default: '#f69',
},
},
methods: {
onClick() {
this.$emit('onClick');
},
},
};
</script>
Button.stories.js:
import Button from '../components/Button.vue';
// More on default export: https://storybook.js.org/docs/vue/writing-stories/introduction#default-export
export default {
title: 'Button',
component: Button
};
// More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Button },
template: '<Button @onClick="onClick" v-bind="$props" />'
});
export const Red = Template.bind({});
Red.args = {
label: 'Red',
backgroundColor: 'red'
};
export const Blue = Template.bind({});
Blue.args = {
label: 'Blue',
backgroundColor: 'blue'
};
Stories 部署访问
先运行命令:
# npm run build-storybook
yarn build-storybook
根目录下会多一个文件夹storybook-static
,部署即可,本地可以进到目录,然后anywhere 9000
即可访问
其他借鉴的例子
点左上角的logo,可以看到源码。