Skip to content

Menggunakan Vue di Markdown

Di VitePress, setiap file Markdown dikompilasi menjadi HTML dan kemudian diproses sebagai Vue Single-File Component. Ini berarti Anda dapat menggunakan fitur Vue apa pun di dalam Markdown, termasuk templating dinamis, menggunakan komponen Vue, atau logika komponen Vue dalam halaman apa pun dengan menambahkan tag <script>.

Perlu dicatat bahwa VitePress memanfaatkan compiler Vue untuk secara otomatis mendeteksi dan mengoptimalkan bagian konten Markdown yang murni statis. Konten statis dioptimalkan menjadi single placeholder node dan dihilangkan dari payload JavaScript halaman untuk kunjungan awal. Konten tersebut juga dilewati selama client-side hydration. Singkatnya, Anda hanya membayar untuk bagian dinamis pada halaman tertentu.

Kompatibilitas SSR

Semua penggunaan Vue harus kompatibel dengan SSR. Lihat Kompatibilitas SSR untuk detail dan solusi umum.

Templating

Interpolasi

Setiap file Markdown pertama-tama dikompilasi menjadi HTML dan kemudian diteruskan sebagai komponen Vue ke pipeline proses Vite. Ini berarti Anda dapat menggunakan interpolasi gaya Vue dalam teks:

Input

md
{{ 1 + 1 }}

Output

2

Directive

Directive juga berfungsi (perhatikan bahwa secara desain, HTML mentah juga valid di Markdown):

Input

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

Output

1 2 3 

<script> dan <style>

Tag <script> dan <style> tingkat root di file Markdown berfungsi seperti di Vue SFC, termasuk <script setup>, <style module>, dll. Perbedaan utama di sini adalah tidak ada tag <template>: semua konten tingkat root lainnya adalah Markdown. Perhatikan juga bahwa semua tag harus ditempatkan setelah frontmatter:

html
---
hello: world
---

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

const count = ref(0)
</script>

## Konten Markdown

Hitungannya: {{ count }}

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

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

Hindari <style scoped> di Markdown

Ketika digunakan di Markdown, <style scoped> memerlukan penambahan atribut khusus ke setiap elemen di halaman saat ini, yang akan secara signifikan memperbesar ukuran halaman. <style module> lebih disarankan ketika styling dengan cakupan lokal diperlukan di halaman.

Anda juga memiliki akses ke runtime API VitePress seperti helper useData, yang menyediakan akses ke metadata halaman saat ini:

Input

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

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

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

Output

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

Menggunakan Komponen

Anda dapat mengimpor dan menggunakan komponen Vue langsung di file Markdown.

Mengimpor di Markdown

Jika sebuah komponen hanya digunakan oleh beberapa halaman, disarankan untuk mengimpornya secara eksplisit di tempat penggunaannya. Ini memungkinkan komponen tersebut di-code-split dengan benar dan hanya dimuat ketika halaman terkait ditampilkan:

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

# Docs

Ini adalah .md yang menggunakan komponen kustom

<CustomComponent />

## More docs

...

Mendaftarkan Komponen Secara Global

Jika sebuah komponen akan digunakan di sebagian besar halaman, komponen tersebut dapat didaftarkan secara global dengan menyesuaikan instance aplikasi Vue. Lihat bagian terkait di Memperluas Tema Default untuk contohnya.

PENTING

Pastikan nama komponen kustom mengandung tanda hubung atau dalam PascalCase. Jika tidak, ia akan diperlakukan sebagai elemen inline dan dibungkus dalam tag <p>, yang akan menyebabkan hydration mismatch karena <p> tidak memungkinkan elemen blok ditempatkan di dalamnya.

Menggunakan Komponen di Header

Anda dapat menggunakan komponen Vue di header, tetapi perhatikan perbedaan antara sintaks berikut:

MarkdownOutput HTMLHeader yang Diparsing
 # text <Tag/> 
<h1>text <Tag/></h1>text
 # text `<Tag/>` 
<h1>text <code>&lt;Tag/&gt;</code></h1>text <Tag/>

HTML yang dibungkus oleh <code> akan ditampilkan apa adanya; hanya HTML yang tidak dibungkus yang akan diparsing oleh Vue.

TIP

Output HTML dihasilkan oleh Markdown-it, sementara header yang diparsing ditangani oleh VitePress (dan digunakan untuk sidebar dan judul dokumen).

Escaping

Anda dapat meng-escape interpolasi Vue dengan membungkusnya dalam <span> atau elemen lain dengan directive v-pre:

Input

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

Output

This {{ will be displayed as-is }}

Alternatifnya, Anda dapat membungkus seluruh paragraf dalam custom container v-pre:

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

Output

{{ This will be displayed as-is }}

Unescape di Blok Kode

Secara default, semua fenced code block secara otomatis dibungkus dengan v-pre, sehingga tidak ada sintaks Vue yang akan diproses di dalamnya. Untuk mengaktifkan interpolasi gaya Vue di dalam fences, Anda dapat menambahkan suffix -vue ke bahasa, mis. js-vue:

Input

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

Output

js
Hello 2

Perhatikan bahwa ini mungkin mencegah token tertentu disorot sintaksnya dengan benar.

Menggunakan CSS Pre-processor

VitePress memiliki dukungan bawaan untuk CSS pre-processor: file .scss, .sass, .less, .styl dan .stylus. Tidak perlu menginstal plugin khusus Vite untuknya, tetapi pre-processor yang sesuai harus diinstal:

# .scss dan .sass
npm install -D sass

# .less
npm install -D less

# .styl dan .stylus
npm install -D stylus

Kemudian Anda dapat menggunakan yang berikut di Markdown dan komponen tema:

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

Menggunakan Teleports

VitePress saat ini memiliki dukungan SSG untuk teleport ke body saja. Untuk target lain, Anda dapat membungkusnya di dalam komponen bawaan <ClientOnly> atau menyuntikkan markup teleport ke lokasi yang benar di HTML halaman akhir Anda melalui hook postRender.

Details
vue
<script setup lang="ts">
import { ref } from 'vue'
const showModal = ref(false)
</script>

<template>
  <button class="modal-button" @click="showModal = true">Show Modal</button>

  <Teleport to="body">
    <Transition name="modal">
      <div v-show="showModal" class="modal-mask">
        <div class="modal-container">
          <p>Hello from the modal!</p>
          <div class="model-footer">
            <button class="modal-button" @click="showModal = false">
              Close
            </button>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
.modal-mask {
  position: fixed;
  z-index: 200;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.3s ease;
}

.modal-container {
  width: 300px;
  margin: auto;
  padding: 20px 30px;
  background-color: var(--vp-c-bg);
  border-radius: 2px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
  transition: all 0.3s ease;
}

.model-footer {
  margin-top: 8px;
  text-align: right;
}

.modal-button {
  padding: 4px 8px;
  border-radius: 4px;
  border-color: var(--vp-button-alt-border);
  color: var(--vp-button-alt-text);
  background-color: var(--vp-button-alt-bg);
}

.modal-button:hover {
  border-color: var(--vp-button-alt-hover-border);
  color: var(--vp-button-alt-hover-text);
  background-color: var(--vp-button-alt-hover-bg);
}

.modal-enter-from,
.modal-leave-to {
  opacity: 0;
}

.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
  transform: scale(1.1);
}
</style>
md
<ClientOnly>
  <Teleport to="#modal">
    <div>
      // ...
    </div>
  </Teleport>
</ClientOnly>

Dukungan VS Code IntelliSense

Vue menyediakan dukungan IntelliSense bawaan melalui plugin Vue - Official VS Code. Namun, untuk mengaktifkannya untuk file .md, Anda perlu melakukan beberapa penyesuaian pada file konfigurasi.

  1. Tambahkan pattern .md ke opsi include dan vueCompilerOptions.vitePressExtensions di file tsconfig/jsconfig:
json
{
  "include": [
    "docs/**/*.ts",
    "docs/**/*.vue",
    "docs/**/*.md",
  ],
  "vueCompilerOptions": {
    "vitePressExtensions": [".md"],
  },
}
  1. Tambahkan markdown ke opsi vue.server.includeLanguages di pengaturan VS Code:
json
{
  "vue.server.includeLanguages": ["vue", "markdown"]
}

Released under the MIT License.