文件
Storybook 文件

裝飾器

觀看影片教學

裝飾器是一種將 story 包裹在額外「渲染」功能中的方法。許多外掛定義了裝飾器,以使用額外渲染來增強您的 stories,或收集有關您的 story 如何渲染的詳細資訊。

在編寫 stories 時,裝飾器通常用於將 stories 包裹在額外的標記或情境模擬中。

使用額外標記包裹 stories

有些元件需要一個「線束」才能以有用的方式渲染。例如,如果元件直接延伸到其邊緣,您可能希望在 Storybook 內將其間隔開。使用裝飾器為元件的所有 stories 新增間距。

Story without padding

YourComponent.stories.ts|tsx
import type { Meta } from '@storybook/react';
 
import { YourComponent } from './YourComponent';
 
const meta: Meta<typeof YourComponent> = {
  component: YourComponent,
  decorators: [
    (Story) => (
      <div style={{ margin: '3em' }}>
        {/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it  */}
        <Story />
      </div>
    ),
  ],
};
 
export default meta;

Story with padding

模擬「情境」

裝飾器函數的第二個引數是 story 情境,其中包含屬性

  • args - story 引數。您可以在裝飾器中使用一些 args,並將它們放在 story 實作本身中。
  • argTypes- Storybook 的 argTypes 可讓您自訂並微調您的 stories args
  • globals - Storybook 範圍的 全域變數。特別是,您可以使用 工具列功能,讓您可以使用 Storybook 的 UI 來變更這些值。
  • hooks - Storybook 的 API hooks (例如 useArgs)。
  • parameters- story 的靜態中繼資料,最常使用於控制 Storybook 的功能和外掛行為。
  • viewMode- Storybook 目前的活動視窗 (例如畫布、文件)。

此情境可用於根據 story 的引數或其他中繼資料來調整裝飾器的行為。例如,您可以建立一個裝飾器,讓您可以選擇性地將版面配置套用至 story,方法是定義 parameters.pageLayout = 'page' (或 'page-mobile'):

.storybook/preview.tsx
import React from 'react';
 
import type { Preview } from '@storybook/react';
 
const preview: Preview = {
  decorators: [
    // 👇 Defining the decorator in the preview file applies it to all stories
    (Story, { parameters }) => {
      // 👇 Make it configurable by reading from parameters
      const { pageLayout } = parameters;
      switch (pageLayout) {
        case 'page':
          return (
            // Your page layout is probably a little more complex than this ;)
            <div className="page-layout"><Story /></div>
          );
        case 'page-mobile':
          return (
            <div className="page-mobile-layout"><Story /></div>
          );
        default:
          // In the default case, don't apply a layout
          return <Story />;
      }
    },
  ],
};
 
export default preview;

另一個範例,請參閱關於設定模擬提供者的章節,其中示範如何使用相同的技術來變更提供給元件的主題。

使用裝飾器提供資料

如果您的元件是「已連線」且需要側載資料才能渲染,您可以使用裝飾器以模擬方式提供該資料,而無需重構元件以將該資料作為引數。有多種技術可以實現此目的。取決於您確切地載入資料的方式。請在 在 Storybook 中建立頁面章節中閱讀更多資訊。

Story 裝飾器

若要為單一 story 定義裝飾器,請在具名匯出上使用 decorators

Button.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
};
 
export default meta;
type Story = StoryObj<typeof Button>;
 
export const Primary: Story = {
  decorators: [
    (Story) => (
      <div style={{ margin: '3em' }}>
        {/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it  */}
        <Story />
      </div>
    ),
  ],
};

務必確保 story 仍然是受測元件的「純」渲染,並且任何額外的 HTML 或元件僅用作裝飾器,這點非常有用。特別是,當您執行此操作時,來源文件區塊效果最佳。

元件裝飾器

若要為元件的所有 stories 定義裝飾器,請使用預設 CSF 匯出的 decorators

Button.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
  decorators: [
    (Story) => (
      <div style={{ margin: '3em' }}>
        {/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it  */}
        <Story />
      </div>
    ),
  ],
};
 
export default meta;

全域裝飾器

我們也可以透過 .storybook/preview.js 檔案的 decorators 匯出來為所有 stories 設定裝飾器(這是您設定所有 stories 的檔案)。

.storybook/preview.tsx
import React from 'react';
 
import { Preview } from '@storybook/react';
 
const preview: Preview = {
  decorators: [
    (Story) => (
      <div style={{ margin: '3em' }}>
        {/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it  */}
        <Story />
      </div>
    ),
  ],
};
 
export default preview;

裝飾器繼承

如同參數一樣,裝飾器可以定義在全域、元件層級以及單一 story(如我們所見)。

一旦 story 渲染,所有與該 story 相關的裝飾器會依照以下順序執行

  • 全域裝飾器,依照它們定義的順序
  • 元件裝飾器,依照它們定義的順序
  • Story 裝飾器,依照它們定義的順序