preface

Some time ago, I wanted to build a business component management platform, which is similar to the official document of Element-UI. After comparing several widely used tools in the industry (StoryBook, Styleguidist, Docz), I finally chose StoryBook, hence this article.

This article introduces storybook + Vue2. X + Element-UI to building a business component management platform. More of it is a description of the points needed for a personal project for reference. To get a full picture of Storybook, I recommend reading the official documentation.

1. Initialization

You can either create a new VUE project and run the following commands, or you can run the following commands directly on an existing project, the latter being my choice and used as the basis for the description below.

npx sb init
Copy the code

This will appear in the project root directory after normal execution.

├ ─ ─ storybook │ ├ ─ ─ the main, js # story, plug-in, webpack configuration file │ └ ─ ─ the preview. The js # interface view, style and other configuration files

At the same time, the.stories directory is created under the SRC directory. To differentiate the.stories directory from the business code directory, you can migrate the.stories directory elsewhere by changing the path in.storybook/main.js:

"stories": [
    ".. /storybook/**/*.stories.mdx".".. /storybook/**/*.stories.@(js|jsx|ts|tsx)"
 ]
Copy the code

To start the storybook service, run the NPM run storybook command. After executing NPX sb init, several example stories have been created in the.stories folder.

Write Stories for business components based on Element-UI development

(Example business component SelectAutocomplete, with project github address at the end)

2.1 in. Stories created in SelectAutocomplete. Storise. Js file

2.1.1 composition

The Storybook component consists of two basic parts: the base template and individual stories, which are essentially base templates in different states. Here is the basic template:

import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) import SelectAutocomplete from '@/components/SelectAutocomplete'; export default { title: 'SelectAutocomplete', component: SelectAutocomplete, // More argTypes: https://storybook.js.org/docs/vue/api/argtypes / / is commonly used to want to specify the domain of scenarios, such as the limited data of the select argTypes: {showHeader: {defaultValue: True, control: {type: 'Boolean'}, description: 'control whether the header is displayed or not'}, showToggleBtn: {defaultValue: true, control: {type: 'Boolean'}, description: 'toggle to show and hide'}, // The args configured here will apply to all stories, that is, args: {}},}; // More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args const Template = (args, { argTypes }) => ({ props: Object.keys(argTypes), components: { SelectAutocomplete }, template: '<SelectAutocomplete v-bind="$props" />', });Copy the code

2.1.1.1 argTypes

ArgTypes is a feature in Storybook that specifies the behavior of Args. You can control the behavior properties of a rendered component by specifying the type of a parameter or by providing a default value. ArgTypes are usually rendered in two forms:

  • Automatically inferring

    Storybook is automatically inferred from the comments on the properties in the original component when the developer builds the.stories.js file and writes the base template, such as:

/ / filterable: {type: Boolean, default: true}, /** Data binding */ modelVal: {type: [String, Number], default: null}, /** Request the interface url of the drop-down list, when passed resData will not send the interface request (therefore, no need to pass the URL) */ URL: {type: String, default: }, /** Whether to set to uneditable */ disabled: {type: Boolean, default: false}, /** Whether to set to one-click clear content */ clearable: {type: Boolean, default: true}, /** v-for loop set key */ forKey: {type: String, default: "}, /** drop down the value of the corresponding key */ valKey: {type: String, default: 'value'}, /** The key corresponding to the label in the dropdown option */ labelKey: {type: String, default: 'label'}}Copy the code
The effect is shown below:Copy the code

annotationAutomatic inference is used to generate the copy of the description column in the figure above from the comments in the original component. How to set the comment referenceVue + storybook annotationFor example, the description of slots

  • Manual describes

    Add any props you want to describe to the argTypes attribute (see argTypes), such as the default control Settings for a limited enumeration drop-down.

export default {
  title: 'Example/Button'.component: Button,
  argTypes: {
    type: {
      control: { type: 'select' },
      defaultValue: 'primary'.options: ['primary'.'warning'.'info'],}}},Copy the code

2.1.2 Context

When SelectAutocomplete is introduced, Storybook does not trace back to its source layer by layer. For example, in order for SelectAutocomplete to work in Storybook, you need to manually introduce elment UI (ps: Can be imported on demand), which means rendering a component in Storybook needs to provide it with the context it needs.

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
import SelectAutocomplete from '@/components/SelectAutocomplete';
Copy the code

2.1.3 Style preprocessor configuration

Storybook does not compile SCSS code by default, so you need to configure the relevant loader in.storybook/main.js

"webpackFinal": async(config, { configType }) => { config.resolve = { ... config.resolve,alias: {
        ...config.resolve.alias,
        The '@': path.join(__dirname, '.. /src'),
      }
    }
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader'.'css-loader'.'sass-loader'].include: path.resolve(__dirname, '.. / '})),return config
  }
Copy the code

2.1.4 Introduction of common styles

SelectAutocomplete is properly displayed if there are public styles in addition to local styles within the component, which can be introduced in.storybook/preview.js

import '@/styles/index.scss'
Copy the code

2.1.5 to write the story

Although stories are essentially components in different states, such as some stories simply passed into ARGS

// SelectAutocomplete.stories.js

export constParameter Description = template.bind ({});// More on args: https://storybook.js.org/docs/vue/writing-stories/argsParameter Description args = {showToggleBtn: true
};
Copy the code

But if you want to achieve some of the complex interactions you want, write a story as a complete VUE component, such as a cascading story:

Through the above operations can initially achieve a business component parameter description and online operation, but also through the following other configuration optimization or achieve the desired effect of the developer.

2.2 the Parameter

Parameter is the static metadata used to define Stories. It provides configuration parameters for the corresponding Addon (plug-in). For example, configure the Background item in the Toolbar (that is, the background color of the render component’s container) with Parameter.

// Button.stories.js

Primary.parameters = {
  backgrounds: {
    values: [
      { name: 'story-red', value: 'pink' },
      { name: 'story-green', value: 'olive' },
    ],
  },
};
Copy the code

Ps: Global parameter configuration in.storybook/preview.js will be mentioned later.

2.3 Decorators

A Decorator is a design pattern that takes the Story to be decorated as an argument and passes it into a Decorator. The Decorator can add additional information to the Story, giving it new capabilities without changing the Story itself. If the element-UI Select component defaults to 100% of the Docs width when displayed in a decorator, limit the Select component to 300px width:

// SelectAutocomplete.stories.js

export default {
  title: 'SelectAutocomplete',
  component: SelectAutocomplete,
  decorators: [() => ({ template: '<div style="width: 300px"><story/></div>' })],
  argTypes: {
  }
};
Copy the code

  • sidebar

  • Tabs

    Storybook has two tabs: Canvas and Docs. If you want to hide or add tabs, you can configure them globally in.storybook/manager.js, or in Parametes in story, for example

export const Defualt = Template.bind({});
// More on args: https://storybook.js.org/docs/vue/writing-stories/args
Defualt.args = {
  showToggleBtn: true
};
Defualt.parameters = {
  viewMode: 'docs'.// Set the default TAB to docs
  previewTabs: {
    canvas: { // Hide canvas TAB
      hidden: true.disable: true}}}Copy the code
  • toolbar

    The options on the toolbar can be set locally in each story and configured globally in.storybook/preview.js, as in

/* ** Background of the layout should be set to light when the component style is white. You can customize the background of the layout, such as ** background: {default: 'palette', values: [{name: 'palette', value: '#e5e5e5', } ] } */
  backgrounds: {
    default: 'light'
  }
Copy the code

other

  • Actions – Can be used to print emit events on components

    NPM install -d @storybook/addon-actionsCopy the code
    //MyButton.vue
    
    
    <template>
      <div>
    <button @click="btnClick">{{ content }}</button>
      </div>
    </template>
    
    <script>
    export default {
      name: "MyButton".props: {
    content: String,},methods: {
    btnClick() {
      this.$emit("btnClick".this.content); ,}}};</script>
    Copy the code
    //MyButton.stories.js
    
    
    import { action } from "@storybook/addon-actions";
    import MyButton from "./MyButton.vue";
    
    export default {
      title: "MyButton".component: MyButton,
    };
    
    export constThe Actions plug-in =() = > ({
      components: {
    MyButton,
      },
      template: `
    <my-button content="clickMe" @btnClick="btnClick"/>
    `.methods: {
    btnClick: action("btnClick"),}});Copy the code