Skip to content

Usando Vue en Markdown

En VitePress, cada archivo Markdown es compilado para HTML y entonces procesado como un Componente de Archivo Único de Vue. Esto significa que puede usar cualquier funcionalidad de Vue dentro del Markdown, incluyendo la interpolación dinámica, usar componentes Vue o lógica arbitrária de componentes Vue dentro de la página adicionando una tag <script>.

Vale resaltar que VitePress aprovecha el compilador Vue para detectar y optimizar automáticamente las partes puramente estáticas del contenido Markdown. Los contenidos estáticaos son optimizados en nodos de espacio reservado únicos y eliminados de la carga JavaScript de la página para visitas iniciales. Ellos también son ignorados durante la hidratación en el lado del cliente. En resumen, solo paga por las partes dinámicas en cualquier página específica.

Compatibilidad SSR

Todo uso de Vue necesita ser compatible con SSR. Consulte Compatibilidad SSR para detalles y soluciones comunes.

Creación de Templates

Interpolación

Cada archivo Markdown es primero compilado para HTML y después pasado como un componente Vue para la canalización de procesos Vite. Esto significa que puede usar interpolación en el estilo Vue en el texto:

Entrada

md
{{ 1 + 1 }}

Salida

2

Directivas

Las Directivas también funcionan (observe que, por definición, HTML crudo también es válido en Markdown):

Entrada

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

Salida

1 2 3 

<script> e <style>

las tags <script> e <style> en nivel raiz en los archivos Markdown funcionan igualmente como en los componentes de archivo único Vue, incluyendo <script setup>, <style module>, y etc. La principal diferencia aquí es que no hay una tag <template>: todo contenido en nivel raiz es Markdown. Además, observe que todas las tags deben ser colocadas después del frontmatter:

html
---
hello: world
---

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

const count = ref(0)
</script>

## Contenido Markdown

El conteo es: {{ count }}

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

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

Evite <style scoped> en el Markdown

Cuando es usado en Markdown, <style scoped> exige la adición de atributos especiales a cada elemento en la página actual, lo que aumentará significativamente el tamaño de la página. <style module> es preferido cuando es necesaria una estilización localizada en una página.

También tiene acceso a los APIs de tiempo de ejecución VitePress, como el auxiliar useData, que proporciona acceso a los metadados de la página actual:

Entrada

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

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

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

Salida

json
{
  "path": "/usando-vue.html",
  "title": "Usando Vue en Markdown",
  "frontmatter": {},
  ...
}

Usando Componentes

Puede importar y usar componentes Vue directamente en los archivos Markdown.

Importando en el Markdown

Si un componente es usado apenas por algunas páginas, es recomendable importarlos explicitamente donde son usados. Esto permite que ellos sean divididos adecuadamente y cargados apenas cuando las páginas relevantes son mostradas.

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

# Documentación

Este es un archivo .md usando un componente personalizado

<CustomComponent />

## Más documentación

...

Registrando Componentes Globalmente

Si un componente fuera usado en la mayoría de las páginas, ellos pueden ser registrados globalmente personalizando la instancia de la aplicación Vue. Consulte la sección relevante en Extendiendo el Tema por Defecto para un ejemplo.

IMPORTANT

Asegurese de que el nombre de un componente personalizado contenga un hífen o esté en PascalCase. Caso contrario, el será tratado como un elemento alineado y envuelto dentro de una tag <p>, lo que llevará a una incompatibilidad de hidratación pues <p> no permite que elementos de bloque sean colocados dentro de el.

Usando Componentes En Headers

Puede usar componentes Vue en los headers, pero observe la diferencia entre las siguientes sintaxis:

MarkdownHTML de SalidaHeader Procesado
 # texto <Tag/> 
<h1>texto <Tag/></h1>texto
 # texto `<Tag/>` 
<h1>texto <code>&lt;Tag/&gt;</code></h1>texto <Tag/>

El HTML envuelto por <code> será mostrado como es, solamente el HTML que no estuviera envuelto será analizado por Vue.

TIP

EL HTML de salida es realizado por Markdown-it, en cuanto los headers procesados son manipulados por VitePress (y usados tanto en la barra lateral como dentro del título del video).

Escapes

Puede escapar de interpolaciones Vue envolvientdolas en un <span> u otros elementos con la directiva v-pre:

Entrada

md
Esto <span v-pre>{{ será exibido como es }}</span>

Salida

Esto {{ será exibido como es }}

Alternativamente, puede envolver todo el paragrafo en un contenedor personalizadon v-pre:

md
::: v-pre
{{ Esto será exibido como es }}
:::

Output

{{ Esto será exibido como es }}

"Desescape" en bloques de Código

Por defecto, todos los bloques de código cercados son automáticamente envueltos con v-pre, entonces ninguna sintaxis Vue será procesada dentro de ellos. Para permitir la interpolación en el estilo Vue dentro de la valla, puede adicionar el lenguaje con el sufijo -vue, por ejemplo, js-vue:

Entrada

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

Salida

js
Hola 2

Observe que esto puede impedir que ciertos tokens sean realzados correctamente.

Usando Preprocesadores CSS

VitePress poseé soporte embutido para preprocesadores CSS: archivos .scss, .sass, .less, .styl e .stylus. No es necesario instalar plugins específicos de Vite para ellos, pero el propio preprocesados correspondiente debe ser instalado:

# .scss e .sass
npm install -D sass

# .less
npm install -D less

# .styl e .stylus
npm install -D stylus

Entonces puede usar lo siguiente en Markdown y en los componentes del tema:

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

Usando Teleports

VitePress actualmente ofrece soporte a SSG para teleports apenas para el cuerpo. Para otros objetivos, puede envolverlos dentro del componente embutido <ClientOnly> o inyectar la marcación de teleport en la localización correcta en su página final HTML por medio del 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>

Soporte de IntelliSense en VS Code

Vue ofrece soporte para IntelliSense de forma predeterminada mediante el Plugin oficial de Vue para VS Code. Sin embargo, para habilitarlo en archivos .md, es necesario realizar algunos ajustes en los archivos de configuración.

  1. Agrega el patrón .md a las opciones include y vueCompilerOptions.vitePressExtensions en el archivo tsconfig/jsconfig:
json
{
  "include": [
    "docs/**/*.ts",
    "docs/**/*.vue",
    "docs/**/*.md",
  ],
  "vueCompilerOptions": {
    "vitePressExtensions": [".md"],
  },
}
  1. Agrega markdown a la opción vue.server.includeLanguages en el archivo de configuración de VS Code
json
{
  "vue.server.includeLanguages": ["vue", "markdown"]
}

Liberado bajo la licencia MIT