7.3 KiB
| description |
|---|
| Crea y usa un tema personalizado en VitePress para controlar completamente la apariencia y el estilo de tu sitio. |
Usando un Tema Personalizado
Carga de Tema
Puede habilitar un tema personalizado creando un archivo .vitepress/theme/index.js o .vitepress/theme/index.ts (o "archivo de entrada de tema"):
.
├─ docs # raíz del proyecto
│ ├─ .vitepress
│ │ ├─ theme
│ │ │ └─ index.js # entrada de tema
│ │ └─ config.js # archivo de configuración
│ └─ index.md
└─ package.json
VitePress siempre usará el tema personalizado en vez del tema por defecto cuando detecte la presencia de un archivo de entrada de tema. Sin embargo, puede extender el tema por defecto para realizar personalizaciones avanzadas sobre el.
Interfaz del Tema
Un tema personalizado de VitePress es definido como un objeto con la siguiente interfaz:
interface Theme {
/**
* Componente raíz de layout para cada página
* @required
*/
Layout: Component
/**
* Mejora la instancia de la aplicación Vue
* @optional
*/
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
/**
* Extiende otro tema, llamando su `enhanceApp` antes de nuestro
* @optional
*/
extends?: Theme
}
interface EnhanceAppContext {
app: App // instancia de la aplicación Vue
router: Router // Enrutador VitePress
siteData: Ref<SiteData> // Metadata a nivel del sitio
}
El archivo de entrada del tema debe exportar el tema como su exportación por defecto:
// Puede importar archivos Vue directamente en el archivo de entrada del tema
// VitePress ya está preconfigurado con @vitejs/plugin-vue.
import Layout from './Layout.vue'
export default {
Layout,
enhanceApp({ app, router, siteData }) {
// ...
}
}
El valor router es la misma instancia del enrutador VitePress que devuelve useRouter(). Para escuchar los cambios de ruta, asigne manejadores al enrutador:
export default {
enhanceApp({ router }) {
router.onBeforeRouteChange = (to) => {
console.log('navegando a', to)
}
router.onAfterRouteChange = (to) => {
console.log('navegando a', to)
}
}
}
Devuelve false desde onBeforeRouteChange o onBeforePageLoad para cancelar la navegación.
La exportación predeterminada es el único contrato para un tema personalizado, y solo se requiere la propiedad Layout. Por lo tanto, técnicamente, un tema de VitePress puede ser tan simple como un único componente de Vue.
Dentro de su componente de layout, el funciona como una aplicación Vite + Vue 3 normal. Note que el tema también necesita ser compatible con SSR.
Construyendo un Layout
El componente de layout más básico necesita un componente <Content />:
<template>
<h1>¡Layout Personalizado!</h1>
<!-- aquí es donde el contenido markdown será presentado -->
<Content />
</template>
El layout encima simplemente renderiza el markdown de todas las páginas cómo HTML. La primera mejora que podemos adicionar es lidiar con errores 404:
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<template>
<h1>¡Layout Personalizado!</h1>
<div v-if="page.isNotFound">
¡Página 404 personalizada!
</div>
<Content v-else />
</template>
El auxiliar useData() proporciona todos los datos para condicionalmente en tiempo de ejecución mostrar layouts diferentes. Uno de los otros datos que podemos acceder es el frontmatter de la página actual. Podemos aprovechar esto para permitir que el usuario final controle el layout en cada página. Por ejemplo, el usuario puede indicar que la página debe usar un layout especial de la pagina inicial con:
---
layout: home
---
Y podemos ajustar nuestro tema para lidiar con esto:
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>
<template>
<h1>¡Layout Personalizado!</h1>
<div v-if="page.isNotFound">
¡Página 404 personalizada!
</div>
<div v-if="frontmatter.layout === 'home'">
¡Página inicial personalizada!
</div>
<Content v-else />
</template>
Puede, claro está, dividir el layout en más componentes:
<script setup>
import { useData } from 'vitepress'
import NotFound from './NotFound.vue'
import Home from './Home.vue'
import Page from './Page.vue'
const { page, frontmatter } = useData()
</script>
<template>
<h1>¡Layout Personalizado!</h1>
<NotFound v-if="page.isNotFound" />
<Home v-if="frontmatter.layout === 'home'" />
<Page v-else /> <!-- <Page /> renders <Content /> -->
</template>
Consulte la Referencia del API en tiempo de Ejecución para todo lo que está disponible en componentes de tema. Además, puede aprovechar la Carga de datos en Tiempo de Compilación para generar layouts orientados por datos - por ejemplo, una página que lista todos los posts del blog en el proyecto actual.
Distribuyendo un Tema Personalizado
La manera más fácil de distribuir un tema personalizado es proporcionarlo como un repositorio plantilla en GitHub.
Si desea distribuir su tema como un paquete npm, siga estos pasos:
-
Exporta el objeto de tema como exportación predeterminada en la entrada de tu paquete.
-
Si aplica, exporte la definición del tipo de configuración de su tema como
ThemeConfig. -
Si su tema exige ajustes en la configuración de VitePress, exporte esa configuración en un subdirectorio del paquete (por ejemplo,
mi-tema/config) para que el usuario pueda ampliarla. -
Documente las opciones de configuración del tema (Ambos, via archivo y frontmatter).
-
Proporcione instrucciones claras sobre cómo consumir su tema (vea abajo).
Consumiendo un Tema Personalizado
Para consumir un tema externo, importelo y reexportelo a partir del archivo de entrada del tema:
import Theme from 'awesome-vitepress-theme'
export default Theme
Si el tema necesita ser extendido:
import Theme from 'awesome-vitepress-theme'
export default {
extends: Theme,
enhanceApp(ctx) {
// ...
}
}
Si el tema exige una configuración especial de VitePress, también necesitará extenderlo en su propia configuración:
import baseConfig from 'awesome-vitepress-theme/config'
export default {
// extienda la configuración base del tema (de ser necesario)
extends: baseConfig
}
Finalmente, si el tema proporciona tipos para la configuración del tema:
import baseConfig from 'awesome-vitepress-theme/config'
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'awesome-vitepress-theme'
export default defineConfigWithTheme<ThemeConfig>({
extends: baseConfig,
themeConfig: {
// El tipo es `ThemeConfig`
}
})