#vue3 #Histoire
[[Vue3]]のプロジェクトに[[Histoire]]を取り入れてみた。
## インストール
https://histoire.dev/guide/getting-started.html
```console
$ npm i -D histoire
$ npm ls histoire
`--
[email protected]
```
## コマンドの追加
[[package.json]]の`scripts`に追加。
```json
"scripts": {
"story:dev": "histoire dev",
"story:build": "histoire build",
"story:preview": "histoire preview"
}
```
## 動作確認
```console
npm run story:dev
```
`localhost:3000`で画面が表示されればOK。
## [[TypeScript]]の型定義追加
`env.d.ts`に以下を追加。
```ts
/// <reference types="histoire" />
```
[[tsconfig.json]]の`include`に`env.d.ts`を追加。
```json
{
"include": ["env.d.ts"],
}
```
## 設定の追加
`histoire.config.ts`を作成。
```ts
import { defineConfig } from 'histoire'
export default defineConfig({
setupFile: "/src/histoire.setup.ts",
})
```
`histoire.setup.ts`には`main.ts`相応の処理を記載する。[[Element Plus]]や[[AG Grid]]を使う場合だと以下のような感じ。
```ts
import { defineSetupVue3 } from 'histoire/client'
import "./assets/style/common.css";
import "element-plus/dist/index.css";
import ElementPlus from "element-plus";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";
export const setupVue3 = defineSetupVue3(({ app, story, variant }) => {
app.use(ElementPlus)
})
```
## コンポーネントの作成
`TripleButton.vue`を作成。
```html
<script setup lang="ts">
interface Props {
firstLabel?: string;
secondLabel: string;
thirdLabel: string;
}
const props = withDefaults(defineProps<Props>(), {
firstLabel: "first",
});
const emit = defineEmits<{
(e: "click", index: number): void;
}>();
const handleClick = (index: number) => {
emit("click", index);
};
</script>
<template>
<el-button @click="handleClick(1)">{{ props.firstLabel }}</el-button>
<el-button @click="handleClick(2)">{{ props.secondLabel }}</el-button>
<el-button @click="handleClick(3)">{{ props.thirdLabel }}</el-button>
</template>
```
## ストーリーの作成
`TripleButton.story.vue`を作成。
```html
<script setup lang="ts">
import TripleButton from "~/components/TripleButton.vue";
import { hstEvent } from "histoire/client";
</script>
<template>
<Story title="トリプルボタン">
<triple-button
second-label="ボタン2"
third-label="ボタン3"
@click="(i) => hstEvent('Click', { value: i })"
/>
</Story>
</template>
```
ストーリーが表示される。
![[Pasted image 20220607235836.png]]
## ドキュメントの作成
`TripleButton.story.vue`にdocs`タグを追加する。
```html
<docs lang="md">
## hahaha
- hoge
- huga
</docs>
```
![[Pasted image 20220607235651.png]]
## 気に入ったところ
- ストーリーもVueファイルと同じように記述できる
- [[Vite]]とのシームレスな設定共有
- [[TypeScript]]の型補完がちゃんと出る
- `<doc>`タグで[[Markdown]]をそのまま記載できる
- [[Storybook]]よりハマリポイントが少ない(気がする)
## 気になること
### 起動が遅い
`npm run story:dev`に20秒以上かかる。
```console
$ npm run story:dev
Collect stories start all
Collect stories end 21270 ms
```
[[Element Plus]]のsetupが遅そうなので、工夫すれば改善するかも?
### `hstEvent`に値を渡しても表示されない
- [[📝HistoireのhstEventに値を渡しても表示されない]]
### propsがJSON型に推論される
- [[📝HistoireのpropsがJSON型に推論される]]
### Storyを更新したときは自動描画されない
リビルドはされるが、サイドメニューからコンポーネントを再クリックしなければ描画は更新されない。
コンポーネントを更新した場合は自動描画されるので大きな問題はない。