Skip to content

运行时 API

VitePress 提供了一组运行时 API,用于在 Vue 组件和 Markdown 中访问站点数据。

快速导航: useData | useRoute | useRouter | usePrefetch | withBase | defineClientComponent | Content 组件


useData

获取站点和页面的所有数据。

基础用法

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

const {
  site,          // 站点级数据
  page,          // 当前页面数据
  frontmatter,   // 当前页面 frontmatter
  themeConfig,   // 主题配置
  lang,          // 当前语言
  title,         // 页面标题
  description,   // 页面描述
  isDark         // 是否深色模式
} = useData()
</script>

返回值

ts
interface VitePressData {
  // 站点数据
  site: {
    title: string
    description: string
    lang: string
    base: string
    head: HeadConfig[]
  }
  
  // 页面数据
  page: {
    title: string
    titleTemplate: string | boolean
    description: string
    relativePath: string
    filePath: string
    headers: Header[]
    frontmatter: Record<string, any>
    params: Record<string, string>
    isNotFound: boolean
  }
  
  // Frontmatter
  frontmatter: Record<string, any>
  
  // 主题配置
  themeConfig: any
  
  // 当前语言
  lang: string
  
  // 页面标题
  title: string
  
  // 页面描述
  description: string
  
  // 深色模式
  isDark: boolean
}

使用示例

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

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

<template>
  <article>
    <h1>{{ frontmatter.title }}</h1>
    <p>路径: {{ page.relativePath }}</p>
    <p>主题: {{ isDark ? '深色' : '浅色' }}</p>
  </article>
</template>

useRoute

获取当前路由信息。

基础用法

vue
<script setup>
import { useRoute } from 'vitepress'

const route = useRoute()
</script>

<template>
  <p>当前路径: {{ route.path }}</p>
</template>

返回值

ts
interface Route {
  path: string           // 当前路径
  data: PageData         // 页面数据
  component: Component   // 页面组件
}

useRouter

访问路由器进行编程式导航。

基础用法

vue
<script setup>
import { useRouter } from 'vitepress'

const router = useRouter()

function goHome() {
  router.go('/')
}

function goBack() {
  router.go(-1)
}

function goForward() {
  router.go(1)
}
</script>

路由器方法

ts
interface Router {
  // 导航到指定路径
  go(path: string): void
  
  // 刷新当前页面
  reload(): void
  
  // 当前路由
  route: Route
  
  // 导航钩子
  onBeforeRouteChange?: (to: string) => boolean | void
  onBeforePageLoad?: (to: string) => void
  onAfterPageLoad?: (to: string) => void
  onAfterRouteChanged?: (to: string) => void
}

导航钩子示例

ts
import { useRouter } from 'vitepress'
import { onMounted } from 'vue'

export default {
  setup() {
    const router = useRouter()
    
    onMounted(() => {
      router.onBeforeRouteChange = (to) => {
        console.log('即将导航到:', to)
        // 返回 false 取消导航
      }
      
      router.onAfterRouteChanged = (to) => {
        console.log('已导航到:', to)
      }
    })
  }
}

usePrefetch

预加载页面资源。

基础用法

vue
<script setup>
import { usePrefetch } from 'vitepress'

const { prefetch } = usePrefetch()

function prefetchPage() {
  prefetch('/guide/getting-started')
}
</script>

<template>
  <button @mouseover="prefetchPage">
    悬停预加载
  </button>
</template>

withBase

为 URL 添加 base 前缀。

基础用法

vue
<script setup>
import { withBase } from 'vitepress'
</script>

<template>
  <img :src="withBase('/images/logo.png')" />
  <a :href="withBase('/guide/')">指南</a>
</template>

defineClientComponent

定义仅在客户端渲染的组件。

基础用法

vue
<script setup>
import { defineClientComponent } from 'vitepress/client'

// 异步加载组件
const Chart = defineClientComponent(() => {
  return import('./Chart.vue')
})

// 带参数
const Map = defineClientComponent(
  () => import('./Map.vue'),
  // 传递给组件的 props
  { center: [0, 0] }
)
</script>

<template>
  <Chart />
  <Map />
</template>

Content 组件

渲染 Markdown 内容。

基础用法

vue
<script setup>
import { Content } from 'vitepress'
</script>

<template>
  <div class="content">
    <Content />
  </div>
</template>

使用示例

页面标题组件

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

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

<template>
  <header class="page-header">
    <h1>{{ frontmatter.title || page.title }}</h1>
    <p v-if="frontmatter.description">
      {{ frontmatter.description }}
    </p>
    <div v-if="frontmatter.date" class="meta">
      发布于 {{ frontmatter.date }}
    </div>
  </header>
</template>

面包屑组件

vue
<script setup>
import { useRoute } from 'vitepress'
import { computed } from 'vue'

const route = useRoute()

const breadcrumbs = computed(() => {
  const parts = route.path.split('/').filter(Boolean)
  return parts.map((part, index) => ({
    text: part,
    link: '/' + parts.slice(0, index + 1).join('/') + '/'
  }))
})
</script>

<template>
  <nav class="breadcrumb">
    <a href="/">首页</a>
    <span v-for="item in breadcrumbs" :key="item.link">
      / <a :href="item.link">{{ item.text }}</a>
    </span>
  </nav>
</template>

深色模式切换

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

const { isDark, theme } = useData()

function toggleDark() {
  isDark.value = !isDark.value
}
</script>

<template>
  <button @click="toggleDark">
    {{ isDark ? '🌙' : '☀️' }}
  </button>
</template>

相关链接

其他运行时 API

useThemeData

获取主题配置数据。

vue
<script setup lang="ts">
import { useThemeData } from 'vitepress'

const theme = useThemeData()
</script>

<template>
  <nav>
    <a v-for="item in theme.nav" :key="item.link" :href="item.link">
      {{ item.text }}
    </a>
  </nav>
</template>

usePageData

获取页面特定的数据(仅限当前页面)。

vue
<script setup lang="ts">
import { usePageData } from 'vitepress'

const page = usePageData()
</script>

<template>
  <div>
    <p>标题: {{ page.title }}</p>
    <p>路径: {{ page.relativePath }}</p>
    <p>标题列表: {{ page.headers.map(h => h.title).join(', ') }}</p>
  </div>
</template>

useFrontmatter

便捷访问当前页面的 Frontmatter。

vue
<script setup lang="ts">
import { useFrontmatter } from 'vitepress'

const frontmatter = useFrontmatter()
</script>

<template>
  <div v-if="frontmatter.hero">
    <h1>{{ frontmatter.hero.name }}</h1>
  </div>
</template>

useSiteStore

VitePress 提供的全局状态管理,可以在组件间共享数据。

vue
<script setup lang="ts">
import { ref } from 'vue'

// 在 theme/index.ts 的 setup 中提供
const globalState = ref({
  sidebarOpen: false,
  searchQuery: ''
})
</script>

createContentLoader

批量加载和处理 Markdown 文件,常用于生成文章列表、标签页等。

typescript
// .vitepress/data/posts.data.ts
import { createContentLoader } from 'vitepress'

export default createContentLoader('blog/*.md', {
  includeSrc: true,
  excerpt: true,
  transform(rawData) {
    return rawData
      .sort((a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date))
      .map(({ url, frontmatter, excerpt }) => ({
        url,
        title: frontmatter.title,
        date: frontmatter.date,
        excerpt,
        tags: frontmatter.tags || []
      }))
  }
})

defineLoader

定义自定义数据加载器。

typescript
// .vitepress/data/github.data.ts
import { defineLoader } from 'vitepress'

export default defineLoader({
  watch: ['*.md'],
  async load() {
    const response = await fetch('https://api.github.com/repos/vuejs/vitepress')
    const data = await response.json()
    return {
      stars: data.stargazers_count,
      forks: data.forks_count,
      issues: data.open_issues_count
    }
  }
})

withBase

为 URL 添加 base 前缀,确保在子路径部署时路径正确。

vue
<script setup lang="ts">
import { withBase } from 'vitepress'
</script>

<template>
  <img :src="withBase('/images/logo.png')" alt="Logo" />
  <a :href="withBase('/guide/')">指南</a>
</template>

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献