4
2

More than 1 year has passed since last update.

コンポーネントをVSCode上でプレビューできるvue-component-previewが最強だった件

Last updated at Posted at 2023-02-07

Abstract

本記事では、Vue.jsにおいてコンポーネントをプレビューしながらコードを書ける、vue-component-previewを紹介します。(図: プレビューしている様子)
image.png
こちらのプラグインは、本記事をサクッと読んでいただくとわかる通り、かなり"良い"です。
しかしながら、紹介/解説記事がQiitaには恐らくありませんでした。
一方でZennには最後に示した参考記事が一つありましたが、最も基本の機能しか紹介していません。
そこで本記事では、基本機能から始まって公式の紹介でも紹介していない機能までを紹介していきます

VSCodeのお話です。
Vue.jsではscript setup記法 / TypeScriptを採用しています。
環境のセットアップ自体の詳しい解説は行いません。

Vue.jsのセットアップ

いつもの。
本記事ではyarnを用います。
その他でも基本的には大きな違いはないはずなので、yanr以外の方は適宜読み替えてください。

# npm派閥
npm create vite@latest
# yarn派閥
yarn create vite
# pnmp派閥
pnpm create vite

例のごとく、質問に答えていきます。
プロジェクト名はお好みで。本記事では「test-vue-component-preview」とでもしておきます。
もちろん、Vue.js, TypeScriptを選択。

必要なパッケージをインストールしていきます。

cd test-vue-component-preview
# vue等を一括インストール
yarn

拡張機能の導入

Vue and Nuxt Preview (from Volar) をインストールします。

プラグインの導入

プレビュー機能を実現するプラグインを導入します。

yarn add -D vite-plugin-vue-component-preview

次に、vite.config.tsに追記します。

vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
+ import Preview from "vite-plugin-vue-component-preview"


// https://vitejs.dev/config/
export default defineConfig({
- plugins: [vue()],
+ plugins: [Preview(), vue()],
})

続いて、tsconfig.jsonに追記します。

tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"],
+   "types": ["vite-plugin-vue-component-preview/client"],
    "skipLibCheck": true,
    "noEmit": true
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

最後に、src/main.tsに追記します。

src/main.ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
+ import Previewer from "virtual:vue-component-preview"

- createApp(App).mount('#app')
+ const app = createApp(App)
+ app.use(Previewer)
+ app.mount("#app")

virtual:vue-component-previewのエラーが消えなかったりしますが、問題ありません。気にしないでください。
これで.vueファイルを開くと、左下に画面のプレビューが表示されます。
この後作成するボタンなどは、そのファイルを開くと、次の図のようにエクスプローラーの左下に表示されます。
image.png
このプレビューは色々な場所にドラッグアンドドロップで動かせるので、お好みの場所に動かしましょう。
おすすめはターミナルの右ですかね。↓こんな感じで、大きめのモニターだといい感じになると思います。

image.png

Take Over Mode

一部のimport (vueファイルのimport) がエラーを出したりしますが、これは既定のTypeScriptの拡張機能がvueに対応していないからです。
Vue.js向けの拡張機能 Volar でその辺の機能も含めてサポートしているので、Volarをインストールしたら、拡張機能マーケットで @builtin と検索して、TypeScript and JavaScript Language Feature をワークスペースで無効化します。(↓コレ)

image.png

百聞は一見に如かず。
ということで、簡単なコンポーネントでプレビューを見てみます。

シンプルなボタン

シンプルなボタンを定義してみます。

src/component/MyButton.vue
<script setup lang="ts">

</script>

<template>
    <button>MyButton</button>
</template>

image.png

プレビューされました!
なお、viteで自動作成されたsrc/style.cssmain.tsで読み込んでいるため、そのスタイルが当たっています。

Propsどうすんの

propsを使ったボタンを定義してみましょう。

src/component/MyButton.vue
<script setup lang="ts">
interface Props {
    title: string
}
const props = defineProps<Props>()
</script>

<template>
    <button>{{ title }}</button>
</template>

image.png

まぁ当たり前ですが、文字が何も表示されないボタンがプレビューされます。
プレビューする用に、なにかしらのpropsを渡したいところですね。
次のように、<preview>タグを追加してみましょう。

src/component/MyButton.vue
<script setup lang="ts">
interface Props {
    title: string
}
const props = defineProps<Props>()
</script>

<template>
    <button>{{ title }}</button>
</template>

+ <preview lang="md">
+ <slot title="Hello" />
+ </preview>

すると、なんとpropsを反映したプレビューになります
つまりslotタグにコンポーネントが代入されるっぽいです。
image.png
※もしかしたら、即座に反映されないかもしれません。プレビューのタブを閉じて開くなどを試すと、うまく行くかもしれません。

しかもこれ、lang="md"と書いてある通りマークダウンなので、軽いドキュメント書けます。
更に更に、v-forとかが使えるので、次のように異なるpropsを描画とかも可能です。

src/component/MyButton.vue
<script setup lang="ts">
interface Props {
    title: string
}
const props = defineProps<Props>()
</script>

<template>
    <button>{{ title }}</button>
</template>

<preview lang="md">
# MyButton Preview

<script setup lang="ts">
const titles = [
    "こんにちは",
    "Hello"
]
</script>

<template v-for="title in titles">
    <slot :title="title" />
</template>
</preview>

image.png

もうこの時点でかなり強いです!!

previewにはCSSを追加できるっぽい。

プラグインのgithubを見ると、styleタグを追加していました。
色々試してみたところ、トップレベルにtemplateが必ず必要というわけではないことが分かりました
次のように、CSSを当ててv-forしてみる。

src/component/MyButton.vue
<!-- さっきと同じ -->
<preview lang="md">
# MyButton Preview

<script setup lang="ts">
const titles = [
    "こんにちは",
    "Hello"
]
</script>

<div class="button-container">
    <template v-for="title in titles" key="title">
        <slot :title="title" />
    </template>
</div>

<style>
body {
    background-color: grey;
}
.button-container {
    display: flex;
    justify-content: space-around;
}
</style>
</preview>

すると、CSSが反映されてしまう。マジかよ。
image.png

他のコンポーネントをimportすることもできる

src/component/FlexContainer.vueを次のように書いてみる。(実用性はおいておきます。)

src/component/FlexContainer.vue
<script setup lang="ts">
</script>

<template>
    <div class="flex-container">
        <slot />
    </div>
</template>

<style scoped>
.flex-container {
    display: flex;
    justify-content: space-around;
}
</style>

MyButton.vueのpreviewの部分を次のように変更してみる。

src/component/MyButton.vue
<preview lang="md">
# MyButton Preview

<script setup lang="ts">
+ import FlexContainer from "./FlexContainer.vue";
const titles = [
    "こんにちは",
    "Hello"
]
</script>

+ <FlexContainer>
- <div class="button-container">
    <template v-for="title in titles" key="title">
        <slot :title="title" />
    </template>
+ </FlexContainer>
- </div>

- <style>
- body {
-     background-color: grey;
- }
- .button-container {
-     display: flex;
-     justify-content: space-around;
- }
- </style>
</preview>

想定通りのプレビューが出てきてしまった
image.png

Tips

VSCode上だとちっせえよ!

プレビューはブラウザでも開けます
右下に表示されている、青い「Previe Port: 3333」をクリックして、Open in browserを選択します。
http://localhost:3333では、App.vueのプレビューを表示するようです。
src/components/MyButton.vueをプレビューしたい場合、
http://localhost:3333/__preview/src/components/MyButton.vue
のように開く必要があります。(2023/02/07時点)

コンポーネントをimportする話って公式にも書いてなくない?

紹介した最後の例のように、コンポーネントをimportできる話は、実はpreviewのプラグインのgithubにも公式の説明にも載っていません。
この仕様は、プラグインの内部の処理で使われているmarkdonw-itのプラグインの処理に由来していると思われます。

恐らく、このvite-plugin-vue-markdownのドキュメントに書いてあることは大体できるはず。
ただまぁ、補完とかは現状提供されていないので、いずれにしよ大規模なドキュメントとかには向いていないでしょう。Storybookさん「呼んだ?」
個人開発とか、小規模なプロジェクトでは有用かと思います。

previewの中のlang="ts"は必要?

A. 多分不要。
無意識に叩いていたけれど、公式の説明でもlang属性は省略されていました。
必須なのはsetup属性だけだと思われます。

参考

↓ 知ったきっかけ ↓

↓ 公式の紹介 ↓

↓ プレビューのプラグインのgithub ↓

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2