使用Storybook管理UI库

babel-ui库介绍

babel-ui是通天塔可视化使用ui库。目前有AlertAlinkButtonCheckboxMessagesModalToolTip等组件
而这个对于可视化经常使用的ui库,却有以下两个糟点

  1. 没有文档介绍各个组件具体使用方法

    目前为止一直没有文档介绍组件的使用方法。这就导致每次开发都需要去看各个组件的propTypes,甚至去看各个组件的源码实现。

  2. 没法脱离于业务开发

    有的需求需要改动公共组件时,需要在node_modules里调试完之后再同步到babel-ui中。

其实搭建一个类似antdesign的组件官网,就解决以上两个问题。但目前我们ui库受众小且没有专人维护,去投入人力开发并维护一个官网并不是明智之举。

而storybook正好可以快速解决以上问题。

Storybook是啥

Storybook 是React,Vue和Angular最受欢迎的UI组件开发工具。它可以在隔离的环境中开发和设计应用程序;也可以那个使用它来快速构建ui组件的文档

Storybook提供了众多的插件来实现一些高级功能,这些插件都是由核心维护者和众多的社区开发人员维护的。在git上收获了4W+的star。

讲了这么多,来看下babel-ui使用Storybook之后的页面,也可以查看一些示例

Storybook开发流程简介

Storybook提供两种接入方式,一个是使用@storybook/cli工具快速识别package.json中所用框架,自动生成一些相应文件;第二种就是针对不同框架从头开始搭建;

我这边讲下第二种一步步搭建的步骤

  1. npm安装@storybook/react

  2. package.json设置scripts

     "scripts": {   
        "storybook": "start-storybook -p 8000"
      }
    
  3. 根目录下创建.storybook文件夹,并依次创建图示文件(center.js和index.styl)

下面会有关于各个文件的详细介绍,这边先忽略

  1. 新建stories文件并写story

    这里主要配合插件写各个组件的story(是一个可以返回可以渲染到屏幕上的函数)。

.storybook文件夹介绍

Addons.js

这个文件主要是用来注册Storybook的各个插件

import "@storybook/addon-knobs/register";
import "@storybook/addon-notes/register-panel";
import "@storybook/addon-actions/register";
import "@storybook/addon-links/register";

center.js

用来居中中间展示区域,也可使用居中插件代替

import React from "react";

const style = {
    maxWidth: 680,
    margin: '0 auto'
}

export default function(renderStory) {
  return <div style={style}>{renderStory()}</div>
}

config.js

这个文件中主要用来动态加载stories中的文件。同时也可以在此文件中配置storybook的主题以及为所有的story添加统一的插件

import { configure } from "@storybook/react";
//指定story的位置
const req = require.context('../src/stories',true,/\.stories\.js$/) 
function loadStories() {
  req.keys().map(fileName=>req(fileName))
}

configure(loadStories, module);

index.styl

我这边这个文件主要为babel-ui引入一些字体文件,也可以引入一些公用的样式

$fa-font-path = '../node_modules/font-awesome-stylus/fonts'
@import '~font-awesome-stylus/index'

webpack.config.js

Storybook有自己的webpack配置,我们可以在通过此文件自定义webpack配置(V4版本)。使用webpack-merg合并默认配置以及自己的配置

addons(Storybook插件)

Storybook有着丰富的插件去满足所需的需求。目前Storybook5.1版本官方支持的常用react插件如下(详细各个插件信息请点击链接):

  1. knobs

    使用storybook-ui将用户输入的值代替props等传入自己的组件。

    knobs提供了内置的text、boolean、number、color、object、array、select、radios、options、files、date、button类型供选择

    import { text } from '@storybook/addon-knobs'
    
    storiesOf('Icon', module).add('default', () => {
      const name = text('name', 'refresh')
      return (
          <Icon name={name} />
      )
    })
    
    

    这样就可以通过storybook内置的text文本输入来控制icon的name

  1. actions

    用于显示storybook中事件处理程序接收到的数据

    当事件触发时,可以查看事件接收的参数

  2. notes

    为storyies添加文本或者markdown

  3. info

    展示组件的各种详细信息,自动将propTypes,defaultProps生成相应的表格信息

  4. State状态

    1. Storybook-state
    2. @sambego/storybook-state
  5. backgrounds

    更改背景

  6. centered

    居中显示

  7. links

    故事之间相互跳转

    获取故事的url

  8. options

    storybook配置项(storybook v5以上直接在配置)

  9. cssresources

    为全局或者单独的story添加样式

  10. storysource

    是否展示story源码

  11. viewport

    为storybook提供各种机型,更好的进行响应式开发

  12. jest

    单元测试

  13. storyshots

    jest或屏幕快照

如何写Story

在写之前先大概了解下各个方法

StoriesOf

import { storiesOf } from '@storybook/react'

storiesOf('Button', module)

StoriesOf接收两个参数,第一个是story类的名字,第二个参数是用来模块热替换(不传,则每次更改story,都需要手动刷新浏览器)

add

add用来添加story类下的子story;可以链式调用在story类下写多个story

参数1:story的名字

参数2:story在中间区域渲染函数

storiesOf('Button', module)
.add('default',()=>111)
.add('story2',()=>2222)

addDecorator

story的装饰器方法(装饰器是一种用一组通用组件包装故事的方法)

  1. 每个story单独使用

    import { storiesOf,addDecorator } from '@storybook/react'
    storiesOf('Button', module)
    .addDecorator(storyFn => <div style={{ textAlign: 'center' }}>{storyFn()}</div>)
    .add('default',()=>111)
    .add('story2',()=>2222)
    
  2. 在.storybook/config.js全局使用

    import { configure, addDecorator } from "@storybook/react";
    import center from './center.js'
    
    addDecorator(center);
    const req = require.context('../src/stories',true,/\.stories\.js$/)
    function loadStories() {
      req.keys().map(fileName=>req(fileName))
    }
    
    configure(loadStories, module);
    

addParameters

给Storybook添加参数(和addDecorator使用方法类似)

  1. 每个story单独使用

  2. 在.storybook/config.js全局使用

    具体配置信息查看

    import { addParameters } from '@storybook/react'
    //使用addParameters添加Storybook配置
    addParameters({
      options: {   
        isFullscreen: false,
        showNav: true,
        showPanel: true,
        panelPosition: "right",
        hierarchySeparator: /\/|\./,
        hierarchyRootSeparator: /\|/,
        sidebarAnimations: true,
        enableShortcuts: true,
        isToolshown: true,
        theme: create({
          base: "light",
          brandTitle: "babel-ui",
          brandUrl: "http://betah5.m.jd.com/active/babelTower/index.html#/"
        })
      }
    });
    

在stories文件中写各个组件的story

npm run storybook启动Storybook之后,就可以在stories文件中写各个组件的story了。下面用一个例子介绍如何配合插件写一个简单的story

import React from 'react'
import { Button, SpiritButton } from 'Shared'
import { storiesOf } from '@storybook/react'
import { boolean, radios, select } from '@storybook/addon-knobs'
import { action } from '@storybook/addon-actions'
import { enumConstants } from 'Utils/common'

// 默认值
const defaultData = {
    type: '无',
    size: 'large',
    disabled: false,
    spritDisabled: false,
    loading: false,
    spritType: 'primary',
    spritSize: 'large'
}

// button type类型
const typeOptions = enumConstants('primary', 'gray', '无')

// SpiritButton type类型
const spritButtonType = enumConstants('primary', 'ghost', 'transparent')

// button大小类型
const typeSizeOptions = enumConstants('small', 'large', 'biglarge')

// spritbutton大小类型
const spritSizeOptions = enumConstants('small', 'large', '无')

storiesOf('Button', module)
    .add('default', () => {
        const type = radios('type', typeOptions, defaultData.type)
        const disabled = boolean('disabled', defaultData.disabled)
        const size = select('size', typeSizeOptions, defaultData.size)
        return (
            <Button
                {...(type != '无' ? { type } : null)}
                size={size}
                disabled={disabled}
                onClick={action('button被点击')}>
                Hello Button
            </Button>
        )
    })
    .add('SpiritButton', () => {
        const loading = boolean('loading', defaultData.loading)
        const disabled = boolean('disabled', defaultData.spritDisabled)
        const type = radios('type', spritButtonType, defaultData.spritType)
        const size = select('size', spritSizeOptions, defaultData.spritSize)
        return (
            <SpiritButton
                onClick={action('button被点击')}
                loading={loading}
                type={type}
                disabled={disabled}
                {...(size != '无' ? { size } : null)}>
                Hello SpiritButton
            </SpiritButton>
        )
    })

未来与展望

随着Storybook不断更新,5.2版本即将到来,到时将会支持docs插件用来代替info插件。docs可以快速将story自动转换为世界级的文档。这也是为啥目前并没有使用notes插件写md文档的原因之一。由于5.2版本还在开发中,对docs插件感兴趣的同学可查看博客插件git地址

总结

本文只是学习Storybook的一个简短总结,在熟悉各个插件之后接入storybook并不是很难;对于解决babel-ui之前无文档、无法独立业务开发组件的问题还是很不错的实践体验。
Storybook官方文档写的还是不错的,对Storybook有兴趣的同学可以点击链接参看

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值