feat(theme): un-deprecate Theme.setup and compose it across extends (#5404)

fix/live-markdown-options
Divyansh Singh 2 weeks ago committed by GitHub
parent 110209dd32
commit ebbd48c8c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -38,7 +38,12 @@ interface Theme {
*/
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
/**
* Extend another theme, calling its `enhanceApp` before ours
* Runs inside the root component's `setup()`
* @optional
*/
setup?: () => void
/**
* Extend another theme, calling its `enhanceApp` and `setup` before ours
* @optional
*/
extends?: Theme
@ -88,6 +93,26 @@ export default {
Return `false` from `onBeforeRouteChange` or `onBeforePageLoad` to cancel navigation.
The `setup` hook runs inside the root component's `setup()`, so Composition API calls (`onMounted`, `watch`, composables, ...) work there without wrapping the layout component:
```ts [.vitepress/theme/index.ts]
import { watch } from 'vue'
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
setup() {
const { page } = useData()
watch(() => page.value.relativePath, (path) => {
console.log('now viewing', path)
})
}
}
```
With `extends`, each theme's `setup` runs base-first, like `enhanceApp`. It also runs during SSR/SSG rendering, so keep browser-only work inside `onMounted`.
The default export is the only contract for a custom theme, and only the `Layout` property is required. So technically, a VitePress theme can be as simple as a single Vue component.
Inside your layout component, it works just like a normal Vite + Vue 3 application. Do note the theme also needs to be [SSR-compatible](./ssr-compat).

@ -26,8 +26,12 @@ function resolveThemeExtends(theme: typeof RawTheme): typeof RawTheme {
...base,
...theme,
async enhanceApp(ctx) {
if (base.enhanceApp) await base.enhanceApp(ctx)
if (theme.enhanceApp) await theme.enhanceApp(ctx)
await base.enhanceApp?.(ctx)
await theme.enhanceApp?.(ctx)
},
setup() {
base.setup?.()
theme.setup?.()
}
}
}

@ -15,7 +15,8 @@ export interface Theme {
extends?: Theme
/**
* @deprecated can be replaced by wrapping layout component
* Runs inside the root component's `setup()` (during SSR too). With
* `extends`, setups run base-first, like `enhanceApp`.
*/
setup?: () => void

Loading…
Cancel
Save