Skip to content

常见问题

汇总 VitePress 开发过程中的常见问题和解决方案。

安装与配置

Node 版本不兼容

问题:运行时报错 Node.js version is not supported

解决:确保 Node.js 版本 >= 18

bash
node -v
# 输出应 >= 18.0.0

使用 nvm 切换版本:

bash
nvm install 18
nvm use 18

端口被占用

问题Error: listen EADDRINUSE

解决:修改端口或关闭占用进程

ts
// docs/.vitepress/config.mts
export default defineConfig({
  vite: {
    server: {
      port: 3000
    }
  }
})

构建失败

问题:构建时报内存不足

解决:增加 Node.js 内存限制

bash
NODE_OPTIONS="--max-old-space-size=4096" npm run docs:build

Markdown 问题

图片无法显示

问题:图片路径正确但无法显示

解决

  1. 图片放在 docs/public/ 目录
  2. 使用绝对路径:/images/logo.png
markdown
<!-- 正确 -->
![Logo](/images/logo.png)

<!-- 错误 -->
![Logo](./images/logo.png)

自定义容器不生效

问题::: tip 语法没有渲染

解决:确保语法正确

markdown
::: tip 标题
内容
:::

注意:

  • ::: 后要有空格
  • 容器类型正确:tipinfowarningdanger

代码高亮失效

问题:代码块没有语法高亮

解决:指定语言

markdown
```javascript
const a = 1
```

主题问题

样式不生效

问题:CSS 变量修改无效

解决:确保选择器正确

css
/* 全局变量 */
:root {
  --vp-c-brand-1: #646cff;
}

/* 深色模式 */
.dark {
  --vp-c-brand-1: #747bff;
}

组件注册失败

问题Unknown custom element

解决:正确注册组件

ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import MyComponent from './components/MyComponent.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.component('MyComponent', MyComponent)
  }
}

布局插槽不显示

问题:插槽内容不渲染

解决:正确继承默认主题

vue
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>

<template>
  <Layout>
    <template #doc-before>
      内容
    </template>
  </Layout>
</template>

路由问题

页面 404

问题:访问页面显示 404

解决

  1. 检查文件路径和 URL 是否匹配
  2. 确保文件扩展名为 .md
文件URL
docs/guide.md/guide/guide.html
docs/guide/index.md/guide/

链接跳转失败

问题:点击链接无法跳转

解决:使用正确的链接格式

markdown
<!-- 内部链接 -->
[指南](/guide/)
[介绍](/guide/introduction)

<!-- 外部链接 -->
[GitHub](https://github.com)

搜索问题

本地搜索无结果

问题:搜索结果为空

解决

  1. 确保搜索配置正确
  2. 检查页面是否被排除
markdown
---
search: false  # 这会排除当前页面
---

Algolia 配置错误

问题:Algolia 搜索初始化失败

解决:检查凭证配置

ts
export default defineConfig({
  themeConfig: {
    search: {
      provider: 'algolia',
      options: {
        appId: 'YOUR_APP_ID',      // 不是 API Key
        apiKey: 'YOUR_API_KEY',     // Search-Only API Key
        indexName: 'YOUR_INDEX_NAME'
      }
    }
  }
})

部署问题

GitHub Pages 404

问题:部署后页面 404

解决:配置正确的 base 路径

ts
export default defineConfig({
  base: '/repo-name/'  // 你的仓库名
})

静态资源 404

问题:CSS、JS 文件加载失败

解决

  1. 检查 base 配置
  2. 确保资源路径正确
ts
// 如果部署到 https://example.com/docs/
export default defineConfig({
  base: '/docs/'
})

刷新页面 404

问题:SPA 路由刷新后 404

解决:配置服务器重定向

Nginx:

nginx
location / {
  try_files $uri $uri/ $uri.html /index.html;
}

Netlify:

toml
[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

其他问题

热更新失效

问题:修改文件后不更新

解决

  1. 检查文件监听限制
  2. 重启开发服务器
bash
# Linux 增加监听限制
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

控制台警告

问题:控制台大量警告

解决

  1. 修复 Vue 警告:检查组件用法
  2. 修复 MD 警告:检查 Markdown 语法

TypeScript 错误

问题:配置文件 TypeScript 报错

解决:使用正确的文件扩展名和类型

ts
// docs/.vitepress/config.mts
import { defineConfig } from 'vitepress'

export default defineConfig({
  // 配置
})

调试技巧

查看构建产物

bash
# 预览构建结果
npm run docs:preview

开启调试模式

ts
export default defineConfig({
  vite: {
    build: {
      minify: false  // 禁用压缩便于调试
    }
  }
})

检查页面数据

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

const data = useData()
console.log(data)
</script>

PWA 相关

Service Worker 注册失败

问题:PWA 离线功能不工作

解决:确保 HTTPS 环境且 manifest 配置正确

ts
// 检查 manifest 配置
export default defineConfig({
  vite: {
    plugins: [VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: '你的站点名',
        short_name: '站点',
        start_url: '/',
        display: 'standalone'
      }
    })]
  }
})

PWA 注意事项

PWA 功能需要 HTTPS 环境,本地开发时 localhost 例外。

缓存策略问题

问题:更新内容后用户看到的是旧版本

解决:配置合理的缓存策略

ts
// workbox 配置
workbox: {
  runtimeCaching: [
    {
      urlPattern: /^https:\/\/fonts\.googleapis\.com/,
      handler: 'StaleWhileRevalidate'
    }
  ],
  navigateFallback: 'index.html'
}

多语言问题

中英文切换不生效

问题:语言切换后内容未变化

解决:确保文件目录结构正确

docs/
├── zh/               # 中文文档
│   └── guide.md
├── en/               # 英文文档
│   └── guide.md
└── .vitepress/
    └── config.mts
ts
// config.mts 多语言配置
export default defineConfig({
  locales: {
    root: { label: '中文', lang: 'zh-CN' },
    en: { label: 'English', lang: 'en', themeConfig: { /* ... */ } }
  }
})

翻译后搜索不工作

解决:每个语言版本需要独立配置搜索

ts
export default defineConfig({
  locales: {
    root: {
      label: '中文',
      lang: 'zh-CN',
      themeConfig: {
        search: { provider: 'local' }
      }
    },
    en: {
      label: 'English',
      lang: 'en',
      themeConfig: {
        search: { provider: 'local' }
      }
    }
  }
})

VuePress 迁移问题

插件不兼容

问题:从 VuePress 迁移后插件报错

解决:VitePress 使用 Vite 生态,需要替换插件

VuePress 插件VitePress 替代方案
vuepress-plugin-xxxvite-plugin-xxx
@vuepress/plugin-pwa@vite-pwa/vitepress
vuepress-plugin-searchVitePress 内置搜索

主题不兼容

问题:VuePress 主题无法直接使用

解决:VitePress 主题 API 不同,需要适配

ts
// VitePress 主题继承方式
import DefaultTheme from 'vitepress/theme'
export default {
  extends: DefaultTheme,
  // 自定义配置
}

性能相关

首页加载慢

问题:Lighthouse 评分低

解决

ts
// 1. 图片优化
export default defineConfig({
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'vendor': ['vue', 'vue-router']
          }
        }
      }
    }
  }
})

// 2. 使用 modern 模式构建
// package.json
{
  "scripts": {
    "build": "vitepress build docs"
  }
}

// 3. 开启 gzip 压缩(服务器配置)

构建产物过大

问题:构建后的 JS bundle 超过 500KB

解决:分析依赖并优化

bash
# 安装分析工具
npm install -D rollup-plugin-visualizer

# 在 vite.config.ts 中配置
import { visualizer } from 'rollup-plugin-visualizer'

export default {
  plugins: [
    visualizer({
      filename: 'stats.html',
      gzipSize: true
    })
  ]
}

Markdown 高级问题

代码组不渲染

问题::: code-group 语法不生效

解决:VitePress 使用不同的语法

markdown
::: code-group
```npm [npm]
npm install vitepress
```

```yarn [yarn]
yarn add vitepress
```
:::

表格宽度溢出

解决:将表格放入自定义容器或使用横向滚动

markdown
<div style="overflow-x: auto">

| 超长表格... |

</div>

Vue 组件在 Markdown 中不渲染

问题:在 Markdown 中使用 Vue 组件但未显示

解决

  1. 确保组件已注册(全局或增强应用中)
  2. 检查组件名称(使用 PascalCase)
  3. SSR 兼容的组件才支持
vue
<!-- 在 Markdown 中使用 -->
<CustomComponent prop="value" />

下一步

学习 插件扩展 来增强站点功能。


组件开发问题

自定义组件 SSR 报错

问题:组件在构建时报错 window is not defined

解决:确保组件兼容 SSR

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

// 只在客户端执行的代码
onMounted(() => {
  console.log(window.location)
})

// 或使用条件判断
if (import.meta.env.SSR === false) {
  // 客户端代码
}
</script>

组件样式隔离

问题:组件样式影响其他元素

解决:使用 scoped 样式

vue
<style scoped>
.container {
  /* 只作用于当前组件 */
}
</style>

动态导入组件

问题:组件体积大影响首屏加载

解决:使用 defineAsyncComponent 按需加载

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

const HeavyComponent = defineAsyncComponent(() =>
  import('./HeavyComponent.vue')
)
</script>

<template>
  <HeavyComponent />
</template>

插件相关问题

如何开发自定义插件

问题:需要开发 VitePress 插件

解决:使用 Vite 插件 API

ts
// vitepress-plugin-example.ts
import type { Plugin } from 'vite'

export function myPlugin(): Plugin {
  return {
    name: 'vitepress-plugin-example',
    enforce: 'pre', // 或 'post'
    transform(code, id) {
      // 转换代码
      return code
    },
    buildStart() {
      // 构建开始时执行
    }
  }
}

// config.mts 中使用
import { myPlugin } from './plugins/my-plugin'

export default defineConfig({
  vite: {
    plugins: [myPlugin()]
  }
})

常用插件推荐

插件用途安装
@vite-pwa/vitepressPWA 支持npm i -D @vite-pwa/vitepress
vite-plugin-sitemap站点地图npm i -D vite-plugin-sitemap
markdown-it-xxxMarkdown 扩展配置 markdown.config

SEO 相关问题

如何添加结构化数据

问题:需要添加 JSON-LD 结构化数据

解决:在布局中注入脚本

vue
<!-- .vitepress/theme/Layout.vue -->
<script setup>
import { useData } from 'vitepress'

const { page, frontmatter } = useData()

const jsonLd = computed(() => ({
  '@context': 'https://schema.org',
  '@type': 'TechArticle',
  headline: frontmatter.value.title,
  author: { '@type': 'Person', name: frontmatter.value.author }
}))
</script>

<template>
  <slot name="head">
    <script type="application/ld+json" v-html="JSON.stringify(jsonLd)"></script>
  </slot>
</template>

sitemap 配置

问题:如何生成 sitemap

解决:VitePress 2.0 内置支持

ts
export default defineConfig({
  sitemap: {
    hostname: 'https://example.com',
    lastmodDateOnly: true
  }
})

Robots.txt 配置

问题:如何配置爬虫规则

解决:创建 public/robots.txt

txt
User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

环境变量问题

如何配置多环境

问题:开发/生产环境需要不同配置

解决:使用环境变量

ts
// config.mts
const isProd = process.env.NODE_ENV === 'production'

export default defineConfig({
  base: isProd ? '/' : '/',
  title: isProd ? '生产标题' : '开发标题'
})
bash
# .env.production
VITE_API_URL=https://api.example.com

# .env.development
VITE_API_URL=http://localhost:3000

在组件中使用环境变量

vue
<script setup>
// VITE_ 前缀的变量会暴露
const apiUrl = import.meta.env.VITE_API_URL
</script>

部署平台特定问题

Vercel 部署配置

问题:Vercel 部署路由问题

解决:配置 vercel.json

json
{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

Netlify 部署配置

问题:Netlify 构建命令

解决:配置 netlify.toml

toml
[build]
  command = "npm run build"
  publish = "docs/.vitepress/dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Cloudflare Pages 部署

问题:Cloudflare Pages 配置

解决

配置项
构建命令npm run build
输出目录docs/.vitepress/dist
Node 版本18

常见报错处理

Hydration mismatch

问题:服务端渲染与客户端不一致

原因

  1. 使用了 Date.now() 或随机数
  2. 条件渲染依赖浏览器 API

解决

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

// 使用客户端初始化
const clientTime = ref(null)

onMounted(() => {
  clientTime.value = new Date().toLocaleString()
})
</script>

Cannot read property of undefined

问题:访问未定义的对象属性

解决:添加可选链和默认值

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

const { frontmatter } = useData()

// 安全访问
const tags = frontmatter.value?.tags ?? []
</script>

Failed to resolve import

问题:模块导入失败

解决:检查导入路径和别名配置

ts
// config.mts
export default defineConfig({
  vite: {
    resolve: {
      alias: {
        '@': '/docs/.vitepress'
      }
    }
  }
})

安全相关问题

如何防止 XSS 攻击

问题:用户输入内容需要安全处理

解决

ts
// 1. 不要使用 v-html 渲染用户内容
// 2. 使用 DOMPurify 处理富文本
import DOMPurify from 'dompurify'

const safeHtml = DOMPurify.sanitize(userInput)

敏感信息保护

问题:API Key 等敏感信息泄露

解决

ts
// 1. 使用环境变量(以 VITE_ 开头的会暴露到前端)
// 2. 不要在代码中硬编码
// 3. 使用服务端代理处理敏感请求

// vite.config.ts
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true
      }
    }
  }
})

样式相关问题

如何覆盖默认主题样式

问题:需要修改默认主题的样式

解决

css
/* .vitepress/theme/style.css */

/* 修改品牌色 */
:root {
  --vp-c-brand-1: #ff6b6b;
  --vp-c-brand-2: #ee5a5a;
}

/* 修改深色模式 */
.dark {
  --vp-c-brand-1: #ff8787;
  --vp-c-brand-2: #ff6b6b;
}

/* 修改导航栏高度 */
:root {
  --vp-nav-height: 72px;
}

/* 修改侧边栏宽度 */
:root {
  --vp-sidebar-width: 300px;
}

深色模式不生效

问题:切换深色模式后部分样式未更新

解决:使用 CSS 变量而非硬编码颜色

css
/* ❌ 错误:硬编码 */
.custom-box {
  background: #ffffff;
}

/* ✅ 正确:使用变量 */
.custom-box {
  background: var(--vp-c-bg);
}

移动端样式问题

问题:移动端布局错乱

解决:使用响应式断点

css
/* VitePress 内置断点 */
@media (max-width: 768px) {
  /* 移动端样式 */
}

@media (min-width: 769px) and (max-width: 1024px) {
  /* 平板样式 */
}

@media (min-width: 1025px) {
  /* 桌面样式 */
}

PWA 深度问题

Service Worker 更新策略

问题:更新后用户仍看到旧版本

解决:配置自动更新或提示更新

ts
// 自动更新
export default withPwa(defineConfig({
  registerType: 'autoUpdate'
}))

// 提示用户更新
export default withPwa(defineConfig({
  registerType: 'prompt'
}))
vue
<!-- 监听更新事件 -->
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.addEventListener('controllerchange', () => {
      // 新 SW 激活,提示刷新
      if (confirm('发现新版本,是否刷新?')) {
        window.location.reload()
      }
    })
  }
})
</script>

PWA 图标问题

问题:部分设备不显示图标

解决:提供完整的图标集

ts
manifest: {
  icons: [
    // 标准图标
    { src: '/pwa-192x192.png', sizes: '192x192', type: 'image/png' },
    { src: '/pwa-512x512.png', sizes: '512x512', type: 'image/png' },
    // maskable 图标(Android 自适应)
    { src: '/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
    // any 图标
    { src: '/pwa-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'any' }
  ]
}

iOS PWA 问题

问题:iOS 添加到主屏幕后样式异常

解决:添加 iOS 专用 meta 标签

ts
head: [
  // iOS 全屏支持
  ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
  ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'default' }],
  ['meta', { name: 'apple-mobile-web-app-title', content: '应用名' }],
  // iOS 图标
  ['link', { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' }],
  // Safari 固定标签图标
  ['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#6366f1' }]
]

离线页面处理

问题:离线时访问未缓存页面显示空白

解决:配置离线回退页面

ts
workbox: {
  // 离线时回退到首页
  navigateFallback: '/index.html',
  // 排除 API 请求
  navigateFallbackDenylist: [/^\/api/]
}

缓存策略详解

问题:不同资源需要不同缓存策略

解决:根据资源类型配置策略

ts
workbox: {
  runtimeCaching: [
    // 静态资源 - 缓存优先,长期缓存
    {
      urlPattern: /\.(?:png|jpg|svg|webp|woff2)$/,
      handler: 'CacheFirst',
      options: {
        cacheName: 'static-assets',
        expiration: {
          maxEntries: 100,
          maxAgeSeconds: 60 * 60 * 24 * 30 // 30 天
        }
      }
    },
    // API 数据 - 网络优先,短期缓存
    {
      urlPattern: /^https:\/\/api\./,
      handler: 'NetworkFirst',
      options: {
        cacheName: 'api-cache',
        networkTimeoutSeconds: 10,
        expiration: {
          maxEntries: 50,
          maxAgeSeconds: 60 * 60 // 1 小时
        }
      }
    },
    // HTML 页面 - 网络优先
    {
      urlPattern: /\.html$/,
      handler: 'NetworkFirst',
      options: {
        cacheName: 'html-cache'
      }
    },
    // JS/CSS - 边缓存边更新
    {
      urlPattern: /\.(?:js|css)$/,
      handler: 'StaleWhileRevalidate',
      options: {
        cacheName: 'js-css-cache'
      }
    }
  ]
}

动画与交互问题

页面过渡动画闪烁

问题:页面切换时有闪烁

解决:确保过渡动画正确配置

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

const route = useRoute()
const transitionName = ref('fade')

// 根据路由变化设置过渡
</script>

<template>
  <Transition :name="transitionName" mode="out-in">
    <component :is="Component" :key="route.path" />
  </Transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

滚动揭示动画不触发

问题:IntersectionObserver 动画不工作

解决:检查元素可见性和观察器配置

ts
// 确保正确配置
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible')
      }
    })
  },
  {
    threshold: 0.1,  // 元素 10% 可见时触发
    rootMargin: '0px 0px -50px 0px'  // 提前触发
  }
)

prefers-reduced-motion 支持

问题:动画影响部分用户

解决:尊重用户动画偏好

css
/* 默认动画 */
.animated-element {
  animation: slideIn 0.3s ease;
}

/* 尊重用户偏好 */
@media (prefers-reduced-motion: reduce) {
  .animated-element {
    animation: none;
    transition: none;
  }
}

数据加载问题

动态数据加载失败

问题useData 加载自定义数据报错

解决:使用 useFetch 或自定义 composable

ts
// composables/usePosts.ts
import { ref, onMounted } from 'vue'

export function usePosts() {
  const posts = ref([])
  const loading = ref(true)
  const error = ref(null)

  onMounted(async () => {
    try {
      const res = await fetch('/api/posts.json')
      posts.value = await res.json()
    } catch (e) {
      error.value = e
    } finally {
      loading.value = false
    }
  })

  return { posts, loading, error }
}

构建时数据加载

问题:需要在构建时获取数据

解决:使用 data-loadertransformPageData

ts
// config.mts
export default defineConfig({
  transformPageData(pageData) {
    // 在构建时处理数据
    return {
      ...pageData,
      customData: computeSomething(pageData)
    }
  }
})

评论系统集成问题

Giscus 配置错误

问题:Giscus 评论不显示

解决:检查仓库配置和权限

vue
<script setup>
// 确保:
// 1. 仓库是公开的
// 2. Discussions 功能已开启
// 3. 安装了 Giscus App
</script>

<template>
  <div class="giscus-container">
    <script
      src="https://giscus.app/client.js"
      data-repo="owner/repo"
      data-repo-id="R_xxxxx"
      data-category="Announcements"
      data-category-id="DIC_xxxxx"
      data-mapping="pathname"
      data-strict="0"
      data-reactions-enabled="1"
      data-emit-metadata="0"
      data-input-position="top"
      data-theme="preferred_color_scheme"
      data-lang="zh-CN"
      crossorigin="anonymous"
      async
    />
  </div>
</template>

Waline 评论样式问题

问题:Waline 样式与主题冲突

解决:自定义样式覆盖

css
/* 覆盖 Waline 样式 */
.wl-container {
  --waline-font-size: 14px;
  --waline-theme-color: var(--vp-c-brand-1);
  --waline-active-color: var(--vp-c-brand-2);
}

/* 深色模式 */
.dark .wl-container {
  --waline-bgcolor: var(--vp-c-bg);
  --waline-bgcolor-light: var(--vp-c-bg-soft);
}

图片优化问题

图片加载优化

问题:大图影响加载性能

解决:使用现代图片格式和懒加载

html
<!-- 使用 WebP 格式 -->
<picture>
  <source srcset="/image.webp" type="image/webp">
  <source srcset="/image.jpg" type="image/jpeg">
  <img src="/image.jpg" alt="描述" loading="lazy">
</picture>

<!-- 响应式图片 -->
<img
  src="/image-800.jpg"
  srcset="/image-400.jpg 400w, /image-800.jpg 800w, /image-1200.jpg 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
  alt="描述"
  loading="lazy"
>

图片路径问题

问题:构建后图片路径错误

解决:使用正确的路径引用

markdown
<!-- 在 public 目录:使用绝对路径 -->
![Logo](/images/logo.png)

<!-- 与 markdown 同目录:使用相对路径 -->
![Screenshot](./screenshot.png)

<!-- 动态引用(需要 import) -->
<script setup>
import logo from './logo.png'
</script>
<img :src="logo" alt="Logo">

RSS 与订阅问题

RSS 生成配置

问题:需要生成 RSS 订阅源

解决:使用 vite-plugin-rss 或自定义脚本

ts
// vite.config.ts
import rss from 'vite-plugin-rss'

export default {
  plugins: [
    rss({
      title: '我的博客',
      description: '博客描述',
      siteUrl: 'https://example.com',
      copyright: 'Copyright 2026',
      items: [
        // 从 posts 目录读取
      ]
    })
  ]
}

RSS 内容格式问题

问题:RSS 内容显示异常

解决:确保 HTML 内容正确编码

ts
{
  title: post.title,
  link: `https://example.com${post.url}`,
  description: post.excerpt,
  content: post.content, // 完整 HTML 内容
  author: post.author,
  pubDate: new Date(post.date).toUTCString()
}

无障碍访问问题

键盘导航问题

问题:自定义组件无法键盘访问

解决:添加正确的 ARIA 属性和焦点管理

vue
<template>
  <button
    role="tab"
    :aria-selected="isActive"
    :tabindex="isActive ? 0 : -1"
    @click="activate"
    @keydown.enter="activate"
    @keydown.space.prevent="activate"
  >
    标签页
  </button>
</template>

屏幕阅读器支持

问题:内容无法被屏幕阅读器识别

解决:添加语义化标签和 ARIA 标签

vue
<template>
  <nav aria-label="主导航">
    <ul role="menubar">
      <li role="none">
        <a role="menuitem" href="/guide">指南</a>
      </li>
    </ul>
  </nav>

  <!-- 跳过链接 -->
  <a href="#main-content" class="skip-link">
    跳到主要内容
  </a>

  <main id="main-content">
    <!-- 内容 -->
  </main>
</template>

<style>
.skip-link {
  position: absolute;
  top: -100%;
  left: 0;
  z-index: 999;
}

.skip-link:focus {
  top: 0;
}
</style>

颜色对比度问题

问题:文本对比度不足

解决:确保符合 WCAG AA 标准(4.5:1)

css
/* 使用足够对比度的颜色 */
:root {
  --vp-c-text-1: rgba(60, 60, 67);      /* 主文本 */
  --vp-c-text-2: rgba(60, 60, 67, 0.78); /* 次文本 */
  --vp-c-text-3: rgba(60, 60, 67, 0.56); /* 弱文本 */
}

.dark {
  --vp-c-text-1: rgba(255, 255, 245, 0.86);
  --vp-c-text-2: rgba(235, 235, 245, 0.6);
  --vp-c-text-3: rgba(235, 235, 245, 0.38);
}

调试与排错

查看构建产物分析

bash
# 使用 rollup-plugin-visualizer
npm install -D rollup-plugin-visualizer

# 配置后构建会生成 stats.html
npm run build

# 打开分析
open stats.html

开发环境调试

ts
// 开启详细日志
export default defineConfig({
  vite: {
    logLevel: 'info',
    clearScreen: false
  }
})

// Vue Devtools 调试
// 安装 Vue Devtools 浏览器扩展

检查运行时错误

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

onErrorCaptured((err, instance, info) => {
  console.error('Vue Error:', err)
  console.error('Component:', instance)
  console.error('Info:', info)
  // 可以发送到错误监控服务
  return false // 阻止错误继续传播
})
</script>

快速参考表

常用命令

命令说明
npm run dev启动开发服务器
npm run build构建生产版本
npm run preview预览构建结果
npx vitepress --help查看帮助

常用配置路径

文件说明
docs/.vitepress/config.mts主配置文件
docs/.vitepress/theme/index.ts主题入口
docs/.vitepress/theme/style.css全局样式
docs/public/静态资源目录

常见错误速查

错误可能原因解决方案
window is not definedSSR 环境使用浏览器 API使用 onMounted 或条件判断
Hydration mismatchSSR/CSR 内容不一致确保服务端和客户端渲染一致
Unknown custom element组件未注册enhanceApp 中注册
EADDRINUSE端口占用修改端口或关闭占用进程
ENOENT文件不存在检查文件路径
Module not found模块导入失败检查依赖安装和导入路径

下一步

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献