网站https://vitepress.dev/zh/guide/getting-started
npm add -D vitepress@next
npx vitepress init 脚手架创建一个初始化项目,需要回答一些问题:
bash
Where should VitePress initialize the config?
./docs
Where should VitePress look for your markdown files?
./docs
Site title:
网站标题
Site description:
网站介绍
Theme:
默认主题就行
#...后面全部yes或默认
修改运行端口
修改package.json:
"docs:dev": "vitepress dev docs --host --port 5176"
其中--host允许所有主机访问,--port 5176指定端口
运行:npm run docs:dev
构建:npm run docs:build
构建后文件在docs\.vitepress\dist 目录中
主页自动跳转到文档快速开始页(不需要主页)
docs\index.md:
md
<!-- docs/index.md -->
<meta http-equiv="refresh" content="0; url=/quickstart.html" />
# 正在跳转...
如果没有自动跳转,请点击 [进入文档](/quickstart)。
自定义简易主页
docs\index.md:
md
---
title: CrowdPulse 文档
outline: deep # 控制右侧大纲层级(可选:deep / 2 / [2,6] 等)
---
# CrowdPulse 文档
欢迎使用CrowdPulse。你可以从以下章节开始:
## 快速开始
- [注册用户](./login.md)
- [创建推广](./quickstart.md)
## 基础知识
- [用户面板](./user.md)
- [角色说明](./kol.md)
- [计费标准](./price.md)
网站配置:
假设选择的路径为docs目录,则配置文件应该在docs.vitepress\config.mts:
ts
import { defineConfig } from 'vitepress'
export default defineConfig({
title: "CrowdPulse文档", // 网站标题
description: "CrowdPulse文档", // 网站描述
lang: 'zh-CN', // 网站语言影响<html lang="zh-CN">标签
lastUpdated: true, // 根据 git 提交自动显示“最近更新”
// cleanUrls: true, // 生成干净URL,不带.html后缀
// 网站配置
themeConfig: {
nav: [
{ text: '快速开始', link: '/quickstart' } // 导航栏
],
// 侧边栏
sidebar: [
{
text: '基础知识', // 一级标题
collapsed: false, // 手风琴菜单,传递了就自动变为手风琴菜单,false为默认展开,true为默认折叠
items: [ // 二级标题+路由
{ text: '成为用户', link: '/login' },
{ text: '用户面板', link: '/user' },
{ text: '角色说明', link: '/kol' },
]
},
{
text: '推广操作', // 一级标题
collapsed: false, // 手风琴菜单
items: [ // 二级标题+路由
{ text: '创建推广', link: '/quickstart' },
{ text: '计费标准', link: '/price' },
]
},
],
// 启用内置搜索,可选
search: {
provider: 'local', // 启用内置本地搜索
options: {
// (可选)把搜索 UI 文案改成中文
locales: {
root: {
translations: {
button: {
buttonText: '搜索文档', // 按钮文案
buttonAriaLabel: '搜索文档' // 无障碍文案
},
modal: {
noResultsText: '没有找到结果',
resetButtonTitle: '清除查询条件',
displayDetails: '显示详细信息',
backButtonTitle: '返回',
footer: {
selectText: '选择',
navigateText: '切换',
closeText: '关闭'
}
}
}
}
}
}
},
// 下面是菜单中文化(选填)
// 右侧“On this page”下拉的标题
outline: {
label: '本页目录' // 原 "On this page"
},
// 回到顶部按钮
returnToTopLabel: '返回顶部', // 原 "Return to top"
// (可选)其它内置文案
sidebarMenuLabel: '目录',
docFooter: { prev: '上一页', next: '下一页' },
darkModeSwitchLabel: '外观',
lightModeSwitchTitle: '切换到浅色',
darkModeSwitchTitle: '切换到深色',
},
// 可选,生成网站地图
sitemap: {
hostname: 'https://docs.cp.5210010.xyz/docs/'
},
})
静态文件
创建static静态文件目录要在docs目录中(和md文件同级),然后在md中使用的引用
页面加载时获取数据
例如创建一个获取价格的ts文件,docs\price.data.ts:
ts
// 平台价格接口定义
export interface PlatformPrice {
post: string | null // 发帖价格
reply: string | null // 回复价格
retweet: string | null // 转发价格
like: string | null // 点赞价格
quote: string | null // 引用价格
follow: string | null // 关注价格
day: string | null // 日常价格
}
// 价格数据接口定义
export interface PriceData {
facebook: PlatformPrice
telegram: PlatformPrice
x: PlatformPrice
instagram: PlatformPrice
whatsapp: PlatformPrice
}
// 声明导出的数据
declare const data: PriceData
export { data }
export default {
/**
* 异步加载价格数据
* @returns {Promise<PriceData>} 返回各平台的价格信息
*/
async load(): Promise<PriceData> {
try {
// 从 API 获取价格数据
const response = await fetch('http://127.0.0.1:8000/api/price/price_list')
const priceData = await response.json()
return priceData
} catch (error) {
console.error('获取价格数据失败:', error)
// 返回默认数据或空数据
return {
facebook: { post: null, reply: null, retweet: null, like: null, quote: null, follow: null, day: null },
telegram: { post: null, reply: null, retweet: null, like: null, quote: null, follow: null, day: null },
x: { post: null, reply: null, retweet: null, like: null, quote: null, follow: null, day: null },
instagram: { post: null, reply: null, retweet: null, like: null, quote: null, follow: null, day: null },
whatsapp: { post: null, reply: null, retweet: null, like: null, quote: null, follow: null, day: null }
}
}
}
}
然后创建docs\price.md:
md
# 计费标准
当前各平台操作费用(单位:元)
<script setup>
import { data } from './price.data'
// 平台名称映射
const platformNames = {
facebook: 'Facebook',
telegram: 'Telegram',
x: 'X',
instagram: 'Instagram',
whatsapp: 'WhatsApp'
}
// 操作类型映射
const actionNames = {
post: '发帖',
reply: '评论',
retweet: '转发',
like: '点赞',
quote: '引用',
follow: '关注',
day: 'KOL占用每天',
}
// 获取所有平台
const platforms = Object.keys(data)
// 获取所有操作类型
const actions = Object.keys(actionNames)
</script>
<div class="price-container">
<table class="price-table">
<thead>
<tr>
<th class="action-column">操作类型</th>
<th v-for="platform in platforms" :key="platform">
{{ platformNames[platform] }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="action in actions" :key="action">
<td class="action-column">{{ actionNames[action] }}</td>
<td v-for="platform in platforms" :key="platform" class="price-cell">
<span v-if="data[platform][action] !== null" class="price">
${{ data[platform][action] }}
</span>
<span v-else class="not-available">-</span>
</td>
</tr>
</tbody>
</table>
</div>
<style scoped>
/* 这里写样式 */
</style>
这里的md中写html可能会让编辑器显示错乱,但是没报错就行
nginx配置静态网站
假设容器中的/usr/share/nginx路径与/home/nginx_ser/nginx做了映射
ini
server {
listen 80;
server_name docs.cp.5210010.xyz;
root /usr/share/nginx/docs; # 静态根目录映射到容器内 /usr/share/nginx/docs
location = / {
try_files /index.html =404;
}
# 根路由:先找真实文件/目录,最后才会 404
location / {
try_files $uri $uri/ =404; # 先尝试 /path 或 /path/,都不存在才 404
}
# /assets 静态目录:修正 alias 路径,指向 /usr/share/nginx/docs/assets/
location ^~ /assets/ {
alias /usr/share/nginx/docs/assets/; # 注意是 docs 不是 doc,并以 / 结尾
access_log off;
expires 7d;
add_header Cache-Control "public";
try_files $uri =404; # 以 URI 为基准进行匹配,找不到则 404
}
}
不作为独立站部署
docs.vitepress\config.mts:
ts
base: '/docs/', //代表在docs路由下,这样生成的html也会是/docs/下
nginx配置:
ini
location = /docs {
try_files /docs/index.html =404;
}
location = /docs/ {
try_files /docs/index.html =404;
}
location /docs {
try_files $uri $uri/ =404;
}
location ^~ /docs/assets/ {
alias /usr/share/nginx/html/docs/assets/; # 注意是 docs 不是 doc,并以 / 结尾
access_log off;
expires 7d;
add_header Cache-Control "public";
try_files $uri =404; # 以 URI 为基准进行匹配,找不到则 404
}