返回博客

在 Storybook 中使用 Vuetify

借助 Storybook 对 Vite 的原生支持,最大限度地发挥 Vuetify 的作用

loading
Shaun Evening
@Integrayshaun
最后更新
⚠️
自 Storybook 7.0 正式发布以来,发生了一些变化。有关在 Storybook 中集成 Vuetify 的最新指南,请查看我们在集成目录中的秘诀。 

应用设计可能很复杂,包含许多字体、排版、间距和颜色选项。Vuetify 通过提供基于 Google Material Design 指南的预设计主题化组件,简化了这一过程,实现了统一的外观。

Storybook 是一个用于隔离构建 UI 的前端工作台。通过结合 Storybook 和 Vuetify,您可以更快地构建 UI,而无需进行大量繁重的工作。自 Storybook 7.0 起,借助原生支持的 Vite,这变得更加容易。本文将向您展示如何集成这两个工具,以创建一个强大且灵活的开发环境,用于使用 Vuetify 构建用户界面。

在本文中,我们将解释如何

  • 🔌 在 Storybook 中设置 Vuetify
  • 🧱 在您的组件中使用 Vuetify
  • 🎨 一键切换 Vuetify 主题

如果您想查看此秘诀的示例代码,请访问 GitHub 上的示例仓库。让我们开始吧!

A completed example of Vuetify working in Storybook with a theme switcher

在 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 应用中。

使用 Vuetify 组件

让我们更新一些示例组件,改用 Vuetify。我们将使用 ./src/stories/button.vue 中的 Button 组件。

The storybook example button story

目前它看起来还不够 Vuetiful,所以让我们做一些修改。将 ./src/stories/Button.vue 的内容替换为以下代码

<template>
  <v-btn type="button" color="primary" @click="onClick" :variant="variant" :size="size">{{ label }}</v-btn>
</template>

<script>
  import { reactive, computed } from 'vue';

  export default {
    name: 'my-button',
    props: {
      label: {
        type: String,
        required: true,
      },
      primary: {
        type: Boolean,
        default: false,
      },
      size: {
        type: String,
        validator: function (value) {
          return ['small', 'large'].indexOf(value) !== -1;
        },
      },
      backgroundColor: {
        type: String,
      },
    },
    emits: ['click'],
    setup(props, { emit }) {
      props = reactive(props);
      return {
        onClick() {
          emit('click');
        },
        variant: computed(() => props.primary ? 'flat' : 'outlined'),
      }
    },
  };
</script>

现在回到 Storybook 中查看,我们的按钮已经变成了 Vuetify 按钮。它甚至在页面级的 Stories 中也发生了变化。

Updating the button component to use the Vuetify button and seeing the button update in Storybook

使用 globalTypes 添加主题切换工具

Vuetify 自带亮色和暗色主题,但您可以覆盖它们并添加更多主题。为了充分利用您的 Stories,您应该有一种方法来在所有主题之间进行切换。

使用 Storybook 主题切换器从 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 (see below)
      items: [
        { value: "light", title: "Light", left: "🌞" },
        { value: "dark", title: "Dark", left: "🌛" },
      ],
      // Change title based on selected value
      dynamicTitle: true,
    },
  },
};

这段代码将创建一个新的工具栏下拉菜单,用于选择您 Stories 所需的主题。

添加一个 withVuetifyTheme 装饰器

需要有一种方法告知 Vuetify 使用工具栏中选择的主题。这可以通过使用装饰器来实现。

我在 .storybook 目录下创建了一个新文件,名为 withVuetifyTheme.decorator.js,它将获取我们的全局主题值并更新 Vuetify 的当前主题。

// .storybook/withVeutifyTheme.decorator.js
import { useTheme } from "vuetify";

export const DEFAULT_THEME = "light";

export const withVuetifyTheme = (story, context) => {
  const globalTheme = context.globals.theme || DEFAULT_THEME;

  return {
    components: { story },
    setup() {
      const theme = useTheme();

      theme.global.name.value = globalTheme;

      return {
        theme,
      };
    },
    template: `<story />`,
  };
};

现在将此装饰器提供给 Storybook,用它来包裹我们的 Stories。为此,将该装饰器添加到 .storybook/preview.js 中的 decorator 数组中

// .storybook/preview.js
import { setup } from "@storybook/vue3";
import { registerPlugins } from "../src/plugins";
import { withVuetifyTheme } from "./withVuetifyTheme.decorator";

setup((app) => {
  // Registers your app's plugins into Storybook
  registerPlugins(app);
});

/* snipped for brevity */

export const decorators = [withVuetifyTheme];

总结

Vuetify 提供大量现成的Material Design 组件,让构建 Vuetiful 用户界面变得轻而易举。只需几个步骤,您就可以在 Storybook 中设置 Vuetify,创建一个强大的开发环境。

参与其中

如果您在工作中使用 Vuetify,我们很希望您能帮助开发一个能自动应用上述配置的插件。加入 Discord 中的维护者社区参与其中,或者查看插件文档。

加入 Storybook 邮件列表

获取最新消息、更新和发布

7,180开发者及仍在增长

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被成千上万开发者用于生产环境的工具。远程优先。

查看职位

热门文章

组件 Story Format 3 来了

下一代 Story Format,让您更高效
loading
Michael Shilman

Storybook 7 中改进的类型安全性

CSF3 语法结合 TypeScript 的 satisfies,为您带来更严格的类型和改进的开发者体验
loading
Kasper Peulen

Storybook 生态系统 CI

保护 Storybook 用户免受包升级带来的麻烦
loading
Michael Shilman
加入社区
7,180开发者及仍在增长
为何为何选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与其中博客
案例展示探索项目组件术语表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify 以及 CircleCI