返回集成
vuetify

集成Vuetify与 Storybook

Vuetify 是一个基于 Vue 的组件库,其设计遵循 Google 的 Material Design 规范。
先决条件

此教程假设您有一个使用 Vuetify v3 的 Vue 3 应用,并且刚刚使用入门指南设置了 Storybook 7.0 或更高版本。还没有?请按照 Vuetify 的安装说明操作,然后运行

# Add Storybook:
npx storybook@latest init

1. 在 Storybook 中注册 Vuetify

首先,您需要将 Vuetify 的字体加载器和插件添加到 Storybook 配置中。为此,请将以下内容添加到您的.storybook/preview.js文件中

// .storybook/preview.js
 
import { setup } from '@storybook/vue3';
import { registerPlugins } from '../src/plugins';
 
setup((app) => {
  // Registers your app's plugins into Storybook
  registerPlugins(app);
});

在这里,registerPlugins加载 Vuetify 的字体并将所有组件注册到 Storybook 的 Vue 应用中。

2. 创建一个故事包装器组件

接下来,您需要将您的故事包装在 Vuetify 的v-app组件中,以便使用一些较大的布局组件,例如v-app-bar。为此,请在.storybook/中创建一个名为StoryWrapper.vue的组件

<!-- .storybook/StoryWrapper.vue -->
 
<template>
  <v-app>
    <v-main>
      <slot name="story"></slot>
    </v-main>
  </v-app>
</template>
 
<script></script>

3. 创建一个withVuetifyTheme装饰器

现在,创建一个 Storybook装饰器,将您的故事包装在 StoryWrapper 组件中。

下面我在.storybook中创建了一个新文件,名为withVuetifyTheme.decorator.js

// .storybook/withVeutifyTheme.decorator.js
 
import { h } from 'vue';
import StoryWrapper from './StoryWrapper.vue';
 
export const withVuetifyTheme = (storyFn, context) => {
  const story = storyFn();
 
  return () => {
    return h(
      StoryWrapper,
      {}, // Props for StoryWrapper
      {
        // Puts your story into StoryWrapper's "story" slot with your story args
        story: () => h(story, { ...context.args }),
      }
    );
  };
};

现在,在您的preview.js文件中将此装饰器提供给 Storybook。

// .storybook/preview.js
 
import { setup } from '@storybook/vue3';
import { registerPlugins } from '../src/plugins';
import { withVuetifyTheme } from './withVuetifyTheme.decorator';
 
setup((app) => {
  registerPlugins(app);
});
 
/* snipped for brevity */
 
export const decorators = [withVuetifyTheme];

4. 添加主题切换工具

Vuetify 自带亮色和暗色主题,您可以覆盖或添加主题。为了充分利用您的故事,您应该有一种方法可以在所有主题之间切换。

要添加我们的切换器,请在.storybook/preview.js中声明一个名为theme全局类型,并为其提供一个可供选择的支持主题列表。

// .storybook/preview.js
 
export const globalTypes = {
  theme: {
    name: 'Theme',
    description: 'Global theme for components',
    toolbar: {
      icon: 'paintbrush',
      // Array of plain string values or MenuItem shape
      items: [
        { value: 'light', title: 'Light', left: '🌞' },
        { value: 'dark', title: 'Dark', left: '🌛' },
      ],
      // Change title based on selected value
      dynamicTitle: true,
    },
  },
};

此代码将创建一个新的工具栏菜单,用于选择您希望用于故事的主题。

5. 添加主题提供程序

需要有一种方法来告诉 Vuetify 使用工具栏中选择的主题。这可以通过更新我们的StoryWrapper组件和withVuetifyTheme装饰器来实现

首先,为StoryWrapper提供一个themeNameprop,它可以传递给v-app

<template>
  <v-app :theme="themeName">
    <v-main>
      <slot name="story"></slot>
    </v-main>
  </v-app>
</template>
 
<script>
export default {
  props: {
    themeName: String,
  },
};
</script>

现在,使用我们的装饰器将全局theme变量作为 prop 传递给我们的StoryWrapper组件

// .storybook/withVeutifyTheme.decorator.js
 
import { h } from 'vue';
import StoryWrapper from './StoryWrapper.vue';
 
export const DEFAULT_THEME = 'light';
 
export const withVuetifyTheme = (storyFn, context) => {
  // Pull our global theme variable, fallback to DEFAULT_THEME
  const themeName = context.globals.theme || DEFAULT_THEME;
  const story = storyFn();
 
  return () => {
    return h(
      StoryWrapper,
      // give themeName to StoryWrapper as a prop
      { themeName },
      {
        story: () => h(story, { ...context.args }),
      }
    );
  };
};

参与进来

现在您已准备好将 Vuetify 与 Storybook 一起使用。🎉 请查看示例仓库以快速入门。

如果您在工作中使用 Vuetify,我们非常乐意您帮助我们制作一个自动应用上述配置的插件。加入Discord中的维护者团队参与进来,或者查看插件文档

标签
贡献者
  • ShaunEvening
    ShaunEvening