从前有匹马叫代码
心若没有栖息的地方,到哪里都是流浪

根据官方文档说法,storybook 是一个独立构建前端UI组件与页面的车间。

Storybook is a frontend workshop for building UI components and pages in isolation. It helps you develop and share hard-to-reach states and edge cases without needing to run your whole app. Thousands of teams use it for UI development, testing, and documentation. It's open source and free.

使用storybook可以很方便的给组件或者页面生成交互效果和用例,它提供了丰富的功能来让我们使用。


快速上手

首先启动一个项目,这里以React为例:npx create-react-app my-app
然后将storybook集成到工程中,参考官方文档,安装有点慢,然后等安装好之后,启动命令:npm run storybook,
就会在浏览器加载出一个页面,类似这种image
会有一些引导步骤教你这个东西怎么用,这里有一些常用的方法,参考如下:


  1. 如何增加新的测试组件
  2. 如何增加不同属性的测试
  3. 如何进行组件的单元测试
  4. 如何加载远程数据

解答:

  1. 首先在stories/下创建一个*.stories.js|ts的文件,
    在文件中需要默认导出 storybook所需的meta data,
    如:
import Card from '@/components/Card';
export default {
	title:'components/Card',
	component:Card
}

这是最基本的配置,title则对应了页面上左侧的菜单,会根据/自动分级,
2. 如果只像第一步那样配置是加载不出来的,因为没有参数配置
增加参数配置其实就是导出一个对象,如:

export const default_config={}

export const useLabel = {
	args:{label:"天下无贼"}
}

上面导出了两个配置对象,第二个配置对象有一个args字段,该字段即为你的组件的props值,useLabel则会作为页面上的菜单名称显示出来,如图:
image
然后右侧的console会出现该参数对应的控制台
image
在上方会渲染出携带该prop的参数,这样一个基本的组件文档就搞好了,

  1. storybook提供了对组件进行单元测试的方法,即:play属性
export const useColor = {
  args: {
    textColor: "red",
  },
  play: async function ({ canvasElement }) {
    const canvas = within(canvasElement);
    const labelDiv = canvas.getByText("default:card", {
      selector: "div",
    });
    await expect(labelDiv).toHaveStyle({ color: "rgb(255, 0, 0)" });
  },
};

上面的函数意思是:选取到textContent为"default:card"的div,这里指的是组件本身,然后用expect断言测试是否有对应的style,如果有则为测试通过,反之则为失败,如图:
image

补充!:在meta data中可以添加decorator来嵌套组件,代码如图:

export default {
  title: "components/Card",
  component: Card,
  args: {
    onClick: fn(),
  },
  argTypes: {
    textColor: { control: "color" },
  },
  decorators: [
    (Story) => (
      <div style={{ border: "1px solid red" }}>
        <Story />
      </div>
    ),
  ],
};

这样在上方渲染组件的时候,组件就会被包裹在一个红色边框的盒子里

  1. 通过storybook提供的loader来加载远程数据,如代码:
import type { Meta, StoryObj } from '@storybook/react';

import fetch from 'node-fetch';

import { TodoItem } from './TodoItem';

/*
 *👇 Render functions are a framework specific feature to allow you control on how the component renders.
 * See https://storybook.js.org/docs/api/csf
 * to learn how to use render functions.
 */
const meta: Meta<typeof TodoItem> = {
  component: TodoItem,
  render: (args, { loaded: { todo } }) => <TodoItem {...args} {...todo} />,
};

export default meta;
type Story = StoryObj<typeof TodoItem>;

export const Primary: Story = {
  loaders: [
    async () => ({
      todo: await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(),
    }),
  ],
};

官方文档:这里

posted on 2024-03-29 15:53  从前有匹马叫代码  阅读(146)  评论(0编辑  收藏  举报