编写 stories

story 用于展示组件某个状态,每个组件可以包含任意多个 story,用来测试组件的各种场景。根据默认配置,只需要在组件的文件夹中,以 **.component.stories.ts 的格式创建即可。

story 语法

基本编写语法很简单,是 export 任意多个 function,每一个就是一个 story。导出主要分两种:

  1. default export:默认导出,提供组件级别的配置信息,例如以下配置会注明组件的归类,并提供 Button 组件的信息,以便渲染这个组件。

    // Button.stories.ts
    
    import Button from './button.component';
    
    export default {
      title: 'Components/Button',
      component: Button,
    }
  2. named export:命名导出,用以描述 story,如上所说,一个组件可以有若干个 story。

    // Button.stories.ts
    
    // 创建一个模板,方便在后续的 story 中复用
    const Template = (args: Button) => ({
      props: args,
    }); export const Primary = Template.bind({});  // 复制 Template
    Primary.args = { background: '#ff0', label: 'Button' };
    Primary.storyName = "主要状态" // 自定义 story 名 export const Secondary = Template.bind({});
    Secondary.args = { ...Primary.args, label: '222' }; // 复用上一个 story 的配置 export const Tertiary = Template.bind({});
    Tertiary.args = { ...Primary.args, label: '222 } // 再来一个

    通过复制模板 function,可以创建若干个 story,传入不同的参数,就可以分别渲染出组件的不同状态。每个 story 的名字默认是 function 名,也可以自定义。

Args(属性)

上一节看到了怎么去写一个 Story 文件,不过里面反复用到的 args 是什么呢?  
它代表组件的输入属性(Angular 中的 @input(),Vue/React 中的 props),它有 2 个层级,方便灵活配置。

  1. story 层级:

    // Button.stories.ts
    
    const Template = (args: Button) => ({
      props: args,
    }); // 在这个 story 中传入组件属性,只影响当前 story
    export const Primary = Template.bind({});
    Primary.args = {
      primary: true,
      label: 'Primary',
    };
  2. 组件层级:

    // Button.stories.ts
    
    import Button from './button.component';
    
    // 组件层级(默认导出)中传入组件属性,
    // 这个 Button 组件的所有 stories 的 primary 属性都会是 true
    export default {
      title: "Button",
      component: Button,
      args: {
        primary: true,
      },
    }

就像上一节所看到的,不同的 story 的 args 是可以复用的,这里用到了 ES6 的解构语法:

const Primary = ButtonStory.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
} // 复用 Primary story 的 args,并覆盖 primary 属性
const Secondary = ButtonStory.bind({});
Secondary.args = {
  ...Primary.args, // 合并上一个 args 对象
  primary: false,
}

简单的导出几个 function,这个按钮组件的测试用例就写好了

可以看到,这个按钮组件可以独立于项目运行了,并且右边工具栏可以自由更改它的属性,实时查看属性改变后的效果,还可以自动生成组件文档。

有 story 做示例,有实时的控制台,有文档,再也不怕写好的组件别人不知道怎么用了。

额外的配置项

除了写给组件写 story,很多时候也会需要配置插件,或者给组件提供额外的功能,这里看看是如何配置的吧。

Parameters(参数)

Parameters 用以配置 Storybook 和 插件,具有全局、组件、story 三个层级。

Story 拥有大量的插件,以下以简单的 backgrounds 插件举例,它用来控制组件容器的背景色,默认自带黑/白两色。

  1. 全局定义在根目录 .storybook/preview.js 下,会影响所有的 stories。这样配置后,每个 story 界面下都可以选择红/绿两色背景:

    // .storybook/preview.js
     
    export const parameters = {
      backgrounds: {
        values: [
          { name: 'red', value: '#f00' },
          { name: 'green', value: '#0f0' },
        ],
      },
    };
  2. 组件层级下定义,会让这个组件的所有 stories 都可以选择指定的背景色

    // Button.story.ts
    
    export default {
      title: 'Button',
      component: Button,
      parameters: {
        backgrounds: {
          values: [
            { name: 'red', value: '#f00' },
            { name: 'green', value: '#0f0' },
          ],
        },
      },
    };
  3. story 层级下的定义只会影响当前 story,其他 story 就只能选择默认的黑/白两色了。

    // Button.story.ts
    
    export const Primary = Template.bind({});
    Primary.args = {
      primary: true,
      label: 'Button',
    };
    // 红绿背景只在这个 story 下可以选择
    Primary.parameters = {
      backgrounds: {
        values: [
          { name: 'red', value: '#f00' },
          { name: 'green', value: '#0f0' },
        ],
      },
    };

Parameters 的配置是可以继承,同名的子级会覆盖父级的定义。

Decorators(装饰器)

每个 Decorator 也是 function,用来包裹 story,保持原有的 story 不变的情况下,额外给它添加额外的 DOM 元素、引入上下文环境、添加假数据等等。  
和 Parameters 一样,它也可以定义在全局/组件/story 三个层级,每个 Decorator 按定义顺序依次执行,从全局到 story。

例如,用一个额外的 <div> 包裹每个 story 的组件渲染:

// button.stories.ts

import { Meta, Story } from '@storybook/angular';
import { ListComponent } from './list.component'; export default {
  title: 'Example/List',
  component: ListComponent,
  decorators: [
    (storyFunc) => {
      const story = storyFunc();       return {
        ...story,
        template: `<div style="height: 60px">${story.template}</div>`,
      };
    }
  ]
} as Meta;

这样一来,这个列表组件的所有 story,都会展示出它在一个 60 像素高的容器内的呈现效果。

除了给组件包裹额外的元素,再例如为复合组件添加组件依赖:

// List.stories.ts

import { moduleMetadata } from '@storybook/angular';
import { CommonModule } from '@angular/common'; import List from './list.component';
import ListItem from './list-item.component' // 给 list 组件添加它需要的组件和模块依赖
export default {
  title: 'List',
  component: List,
  decorators: [
    moduleMetadata({
      declarations: [ListItem],
      imports: [CommonModule],
    }),
  ],
}; const Template = (args: List) => ({
  component: List,
  props: args,
});

就像平常需要在 ngModule 中声明似的,moduleMetadata 装饰器可以轻松测试各种组件,让你能在 Storybook 中从小到大搭建组件库。

文章内容来源:
Storybook 组件驱动开发(一)-- 基本使用 https://segmentfault.com/a/1190000039308365

转载本站文章《storybook 编写stories的story基础语法》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/storybook/8897.html

storybook 编写stories的story基础语法的更多相关文章

  1. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  2. Python基础语法

    学习一门编程语言,通常是学习该语言的以下几个部分的内容: 基础语法:如,变量的声明与调用.基本输出语句.代码块语法.注释等: 数据类型:通常都为 数字.字符串.布尔值.数组.链表.Map.Set等: ...

  3. javascript基础语法——词法结构

    × 目录 [1]java [2]定义 [3]大小写[4]保留字[5]注释[6]空白[7]分号 前面的话 javascript是一门简单的语言,也是一门复杂的语言.说它简单,是因为学会使用它只需片刻功夫 ...

  4. JSP/Servlet基础语法

    相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp ...

  5. Verilog HDL基础语法讲解之模块代码基本结构

    Verilog HDL基础语法讲解之模块代码基本结构   本章主要讲解Verilog基础语法的内容,文章以一个最简单的例子"二选一多路器"来引入一个最简单的Verilog设计文件的 ...

  6. Python 基础语法

    Python 基础语法 Python语言与Perl,C和Java等语言有许多相似之处.但是,也存在一些差异. 第一个Python程序 E:\Python>python Python 3.3.5 ...

  7. VB execl文件后台代码,基础语法

    Excel宏与VBA 程序设计实验指导1 实验1 Excel宏与VBA 语法基础 一.实验目的 1.熟练掌握录制宏.执行宏.加载宏的方法: 2.熟练使用Excel VBA编辑环境,掌握VBA的编辑工具 ...

  8. 第2章 Python基础语法--Hello python

    第2章 基础语法 2.1 基本介绍 2.1.1 Hello python 每个语言的开始都是从”HelloWorld”开始的,我们也不例外.打开已经安装好的Python编译环境,至于Python如何安 ...

  9. less学习:基础语法总结

    一. less是什么 Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充. 注意1):less使用. ...

  10. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

随机推荐

  1. CSP 2023 游记

    省流:把 #define int long long 写在快读下面,找到答案了不 break. Day -1 手速大赛很有趣,但有人不认识 Aigony 我不说是谁. Day 0 睡大觉,给小朋友讲考 ...

  2. 洛谷P1144

    最短路计数 题目描述 给出一个 \(N\) 个顶点 \(M\) 条边的无向无权图,顶点编号为 \(1\sim N\).问从顶点 \(1\) 开始,到其他每个点的最短路有几条. 输入格式 第一行包含 \ ...

  3. NewStarCTF 2023 公开赛道 WEEK4|MISC 部分WP

    R通大残 1.题目信息 R通大残,打了99,补! 2.解题方法 仔细分析题目,联想到隐写的R通道. 首先解释一下:R是储存红色的通道,通道里常见有R(红).G(绿).B(蓝)三个通道,如果关闭了R通道 ...

  4. games101-1 光栅化与光线追踪中的空间变换

    在学习了一些games101的课程之后,我还是有点困惑,对于计算机图形学的基础知识,总感觉还是缺乏一些更加全面的认识,幸而最*在做games101的第五次作业时,查询资料找到了scratchpixel ...

  5. mediakit 源码 轻微微 学习总结

    mediakit 源码 轻微微 学习总结 概要 项目地址:https://github.com/ZLMediaKit/ZLMediaKit 此项目我们把他做为一个流媒体服务器,我们会有srt和rtsp ...

  6. Kubernetes 中的服务注册与发现原理分析

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 对k8s有点了解技术人员,应该都只知道k8s是有服务注册发现的,今天就分析下这个原理,看看怎么实现的. 什么是服务注册与发 ...

  7. 使用halo快速搭建应用文档中心

    背景 之前我写了一篇,用gitbook搭建文档中心,gitbook是一款搭建博客的技术,是静态博客技术,不带后台管理系统.不带数据库,要发文章的话,是通过提供markdown文件,渲染成html,通过 ...

  8. springboot的缓存和redis缓存,入门级别教程

    一.springboot(如果没有配置)默认使用的是jvm缓存 1.Spring框架支持向应用程序透明地添加缓存.抽象的核心是将缓存应用于方法,从而根据缓存中可用的信息减少执行次数.缓存逻辑是透明地应 ...

  9. [c/c++][考研复习笔记]内部排序篇学习笔记

    考研排序复习笔记 插入排序 #include<stdio.h> #include<stdlib.h> #define MaxSize 9 //折半插入排序 void ZBIns ...

  10. 初次认识 Git (v2.x)

    什么是版本控制? 版本控制,也称为源代码控制,是一种跟踪和管理软件代码变更的实践.版本控制系统是软件工具,可帮助软件团队管理源代码随时间推移而发生的变更.随着开发环境的加速,版本控制系统可以帮助软件团 ...