【Nuxt 2】Storybookの導入
Storybook とは
Storybook とは、Vue.js などのコンポーネント開発を補助するツールです。 作成したコンポーネントをある程度自動でドキュメント化できるため、コンポーネントの仕様をプロジェクトメンバーで共有できたりします。
Vue.js の Storybook についてはこちらにチュートリアルがありますので、よろしければ参考にしてください。 この記事では NuxtJS への導入について記述していきます。
Storybook の導入
インストール
NuxtJS への導入方法はいくつかありますが、@nuxtjs/storybookを使用します。
npm install --save-dev @nuxtjs/storybook postcss@latest
ストーリー
まずは動作を確認するために、以下のようにMyButton
コンポーネントと Storybook 用のファイル(**.stories.js
)を作成します。
これは好みですが、Storybook 用にstories
のようなフォルダを作成したりします。
components/
├ stories/
│ └ MyButton.stories.js
└ MyButton.vue
<template>
<button
:disabled="disabled"
:style="style"
@click="onClick"
>
<slot />
</button>
</template>
<script>
export default {
props: {
color: {
type: String,
default: undefined
},
disabled: {
type: Boolean,
default: false
}
},
computed: {
style() {
return {
'background-color': this.color
}
}
},
methods: {
onClick(event) {
this.$emit('click', event)
}
}
}
</script>
import MyButton from '../MyButton'
export default {
title: 'Button',
component: MyButton,
}
//1つ目が基準。
export const Default = () => '<my-button>Button</my-button>'
//2つ目以降がstoriesとして追加される。
export const Color = () => `
<div>
<my-button color="red">Red</my-button>
<my-button color="blue">Blue</my-button>
<my-button color="green">Green</my-button>
</div>
`
起動
Storybook は、以下のコマンドで起動します。 コンソールに表示された URL にアクセスして、起動していることを確認してください。
npx nuxt storybook
画面中の Docs を選択すると、画像のような画面が表示されるはずです。 詳細は後述します。
アドオン
Storybook は、アドオンとして機能を追加することができます。 アドオンの追加方法については後述します。
@nuxtjs/storybook
には、デフォルトで@storybook/addon-essentials
というアドオンが導入されています。
このアドオンにより、以下のアドオンがまとめて導入されます。
それぞれのアドオンの説明は割愛します。
設定
Storybook に関する設定は、nuxt.config.js
のstorybook
に記述します。
export default {
//...
storybook: {
//アドオンを追加します。
//@storybook/addon-essentialsは設定不要です。
addons: [
'@storybook/addon-controls',
{
name: '@storybook/preset-scss',
options: {
cssLoaderOptions: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]',
}
}
}
],
//ストーリーファイルの場所を指定します。
stories: [
'~/components/stories/*.stories.js'
],
//起動するポートを設定します。
port: 4000,
//パラメーターは、アドオンなどを制御するための値です。
//ここでは、すべてのストーリーに適用されるグローバルパラメーターを設定します。
parameters: {
backgrounds: {
default: 'white',
values: [
{ name: 'white', value: '#ffffff' },
{ name: 'gray', value: '#aaaaaa' }
]
}
},
//ストーリーに適用するタグを設定します。
decorators: [
'<div id="__nuxt"><story /></div>'
]
}
}
ストーリーの作成
上述したMyButton.stories.js
を基に、ストーリーの作成について記述します。
タイトル
ストーリーのタイトルは、コード中のexport default {}
のtitle
に設定します。
タイトルをComponent/Button
、Component/TextField
のようにスラッシュで区切ることで、グルーピングが可能です。
ストーリーの追加
ファイルにexport const <Story Name>
を定義することでストーリーを追加できます。
上例では、Default と Color というストーリーを定義しています。
ストーリーが 1 つの場合、タイトルと同じ名前にすることで余計な階層を省略できます。
Docs では、1 つ目に定義したものが基準のストーリーとなり、コンポーネント情報の表が表示されます。 2 つ目以降に定義したものが Stories として表示されます。
argTypes
export default {}
にargTypes
を設定することで、コンポーネントの情報を設定します。
ある程度は自動で設定されるようになっているため、必要なものだけ設定すれば OK です。
export default {
title: 'Button',
component: MyButton,
argTypes: {
color: {
description: '`background-color`を設定します。',
defaultValue: 'red',
control: {
type: 'select',
options: ['red', 'blue', 'green']
}
},
disabled: {
description: 'ボタンを使用不可に設定します。'
},
click: {
description: 'クリック時に発火するイベントです。'
},
default: {
description: 'デフォルトのslotです。'
}
}
}
argTypes
の設定を反映するために、1 つ目のストーリーを以下のように変更します。
export const Default = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { MyButton },
template: '<my-button v-bind="$props">Button</my-button>'
})
Control
Control は、コンポーネントのプロパティを動的に変更するための機能です。 ここでプロパティを変更することで、コンポーネントの動きや見た目の変化を確認することができます。
上記のargTypes
の設定により、表に Control の列が追加されています。
ここに設定された入力欄により、プロパティを動的に変更することができます。
この入力欄の種類は、コンポーネントのプロパティタイプによって自動で設定されます。
種類を変更したい場合は、argTypes
のcontrol
を設定します。
Control の種類(type
)には、以下のものがあります。
type | 例 |
---|---|
boolean | control { type: 'boolean' } |
number | control { type: 'number', min: 0, max: 50, step: 5 } |
range | control { type: 'range', min: 0, max: 50, step :5 } |
text | control { type: 'text' } |
date | control { type: 'date' } |
color | control { type: 'color' } |
object | control { type: 'object' } |
file | control { type: 'file' } |
radio | control { type: 'radio' }, options ['one', 'two', 'three'] |
inline-radio | control { type: 'inline-radio' }, options ['one', 'two', 'three'] |
check | control { type: 'check' }, options ['one', 'two', 'three'] |
inline-check | control { type: 'inline-check' }, options ['one', 'two', 'three'] |
select | control { type: 'select' }, options ['one', 'two', 'three'] |
multi-select | control { type: 'multi-select' }, options ['one', 'two', 'three'] |
またdefaultValue
により、Control の初期値を設定することができます。
Actions
イベントの動作を確認するためにaction
を設定します。
まずはargTypes
の対象のイベントにaction
を設定します。
export default {
//...
argTypes: {
//...
click: {
description: 'クリック時に発火するイベントです。',
action: 'click'
}
}
}
次に対象のtemplate
にイベントを設定します。
export const Default = (args, { argTypes }) => ({
//...
template: '<my-button v-bind="$props" @click="click">Button</my-button>'
})
Canvas 画面に移動し、対象のイベントを発火させます。 イベントが発火すると、画面下の Actions に情報が表示されます。