You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vitepress/docs/ja/guide/using-vue.md

9.5 KiB

MarkdownでVueを使う

VitePress では、各 Markdown ファイルはまず HTML にコンパイルされ、その後 Vue の単一ファイルコンポーネントSFC として処理されます。つまり、Markdown 内で Vue のあらゆる機能が使えます。動的テンプレート、Vue コンポーネントの利用、<script> タグを追加してページ内ロジックを書くことも可能です。

なお、VitePress は Vue のコンパイラを利用して、Markdown コンテンツの純粋に静的な部分を自動検出・最適化します。静的コンテンツは単一のプレースホルダノードに最適化され、初回訪問時の JavaScript ペイロードから除外されます。クライアント側のハイドレーションでもスキップされます。要するに、そのページで動的な部分に対してだけコストを支払うことになります。

::: tip SSR 互換性 Vue の使用は SSR 互換である必要があります。詳細と一般的な回避策は SSR 互換性 を参照してください。 :::

テンプレート記法

補間

各 Markdown は最初に HTML にコンパイルされ、その後 Vite の処理パイプラインで Vue コンポーネントとして扱われます。つまり、テキスト内で Vue 風の補間が使えます。

入力

{{ 1 + 1 }}

出力

{{ 1 + 1 }}

ディレクティブ

ディレクティブも動作します(設計上、生の HTML は Markdown でも有効です)。

入力

<span v-for="i in 3">{{ i }}</span>

出力

{{ i }} 

<script><style>

Markdown ファイルのルート直下に置く <script><style> タグは、Vue の SFC と同様に動作します(<script setup><style module> などを含む)。大きな違いは <template> タグが無い点で、その他のルート直下のコンテンツは Markdown になることです。すべてのタグはフロントマターのに配置してください。

---
hello: world
---

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

## Markdown コンテンツ

現在の値: {{ count }}

<button :class="$style.button" @click="count++">Increment</button>

<style module>
.button {
  color: red;
  font-weight: bold;
}
</style>

::: warning Markdown での <style scoped> は避ける Markdown で <style scoped> を使うと、そのページ内のすべての要素に特殊な属性を付与する必要があり、ページサイズが大きく膨らみます。ページ単位でローカルスコープが必要な場合は <style module> を推奨します。 :::

VitePress のランタイム API現在ページのメタデータにアクセスできる useData ヘルパー)も利用できます。

入力

<script setup>
import { useData } from 'vitepress'

const { page } = useData()
</script>

<pre>{{ page }}</pre>

出力

{
  "path": "/using-vue.html",
  "title": "Using Vue in Markdown",
  "frontmatter": {},
  ...
}

コンポーネントの利用

Markdown ファイルで、Vue コンポーネントを直接インポートして使用できます。

Markdown 内でのインポート

特定のページでしか使わないコンポーネントは、そのページで明示的にインポートするのがおすすめです。これにより適切にコード分割され、該当ページでのみ読み込まれます。

<script setup>
import CustomComponent from '../components/CustomComponent.vue'
</script>

# ドキュメント

これはカスタムコンポーネントを使う .md です

<CustomComponent />

## 続き

...

グローバル登録

ほとんどのページで使うコンポーネントは、Vue アプリインスタンスをカスタマイズしてグローバル登録できます。例は デフォルトテーマの拡張 を参照してください。

::: warning 重要 カスタムコンポーネント名にはハイフンを含めるか、PascalCase を使用してください。そうでない場合、インライン要素として解釈されて <p> タグ内にラップされ、ブロック要素が入れられないためハイドレーション不整合を引き起こします。 :::

見出し内でのコンポーネント利用

見出し内で Vue コンポーネントを使うこともできますが、次の書き方の違いに注意してください。

Markdown 出力 HTML 解析される見出し
 # text <Tag/> 
<h1>text <Tag/></h1> text
 # text `<Tag/>` 
<h1>text <code>&lt;Tag/&gt;</code></h1> text <Tag/>

<code> に包まれた HTML はそのまま表示されます。包まれていない HTML だけが Vue によってパースされます。

::: tip 出力 HTML の生成は Markdown-it が担当し、見出しの解析は VitePress が担当します(サイドバーやドキュメントタイトルに利用)。 :::

エスケープ

v-pre ディレクティブを付けた <span> などでラップすることで、Vue の補間をエスケープできます。

入力

This <span v-pre>{{ will be displayed as-is }}</span>

出力

This {{ will be displayed as-is }}

段落全体を v-pre のカスタムコンテナで囲む方法もあります。

::: v-pre
{{ This will be displayed as-is }}
:::

出力

::: v-pre {{ This will be displayed as-is }} :::

コードブロック内でのアンエスケープ

既定では、フェンス付きコードブロックは自動で v-pre が付与され、Vue の構文は処理されません。フェンス内で Vue 風の補間を有効にするには、言語に -vue サフィックスを付けます(例:js-vue)。

入力

```js-vue
Hello {{ 1 + 1 }}
```

出力

Hello {{ 1 + 1 }}

この方法では、一部のトークンが正しくシンタックスハイライトされない場合があります。

CSS プリプロセッサの利用

VitePress は CSS プリプロセッサ(.scss.sass.less.styl.stylus)を標準サポートしています。Vite 固有のプラグインは不要ですが、各プリプロセッサ本体のインストールは必要です。

# .scss / .sass
npm install -D sass

# .less
npm install -D less

# .styl / .stylus
npm install -D stylus

その後、Markdown やテーマコンポーネントで次のように使えます。

<style lang="sass">
.title
  font-size: 20px
</style>

Teleport の利用

現時点で VitePress は、SSG における Teleport を body へのみサポートしています。その他のターゲットへ Teleport したい場合は、組み込みの <ClientOnly> でラップするか、postRender フックで最終ページ HTML の適切な位置に Teleport のマークアップを注入してください。

::: details <<< @/components/ModalDemo.vue :::

<ClientOnly>
  <Teleport to="#modal">
    <div>
      // ...
    </div>
  </Teleport>
</ClientOnly>

VS Code の IntelliSense サポート

Vue は Vue - Official VS Code plugin により、標準で IntelliSense を提供します。ただし .md ファイルでも有効にするには、設定ファイルをいくつか調整する必要があります。

  1. tsconfig/jsconfig の includevueCompilerOptions.vitePressExtensions.md パターンを追加します。

::: code-group

{
  "include": [
    "docs/**/*.ts",
    "docs/**/*.vue",
    "docs/**/*.md",
  ],
  "vueCompilerOptions": {
    "vitePressExtensions": [".md"],
  },
}

:::

  1. VS Code の設定で、vue.server.includeLanguagesmarkdown を追加します。

::: code-group

{
  "vue.server.includeLanguages": ["vue", "markdown"]
}

:::