🗒初墨
🍊Hello,各位好,我是面包!
以为建站只能复制模板?这篇指南让你用Vitepress+GPT组合技,从零搓出会聊天的智能博客!内含防秃指南、代码冷知识,以及如何把ChatGPT调教成你的24小时编程陪练 (◕ᴗ◕✿)
前置条件
环境依赖
- node.js 构建工程需要
- vscode 文本编辑器-修改代码
- git 部署到github page上
Vitepress从零出发
安装Vitepress
首先创建你的博客空文件夹vitepress[你的博客名称]
mkdir vitepress进入此文件夹
cd vitepress然后安装vitepress
pnpm add -D vitepress
vitepress初始化
pnpm vitepress init
安装vue库
pnpm add -D vue
本地启动静态网站
pnpm run docs:dev
本地构建网站
pnpm run docs:buildgit小技巧
改变github上传仓库的位置太麻烦,可以直接将先前仓库的.git文件夹直接复制到新文件夹里面就可以了
前置依赖
npm|pnpm|yarn检查安装命令:
npm -v安装Vitepress
npm add -D vitepress初始化
npx vitepress init本地启动静态网站
run docs:dev本地启动静态网站
run docs:build小纸条
- npm install是用来安装项目依赖的命令。当你克隆一个使用npm管理依赖的项目时,或者想为你的项目添加新的依赖时,你通常需要运行这个命令。这个命令会自动解析项目的package.json文件,安装所有需要的依赖包。安装后的依赖包会被放在项目根目录下的node_modules文件夹中。
- npm run dev是一个用于启动开发环境的命令。这个命令通常会运行一些脚本,这些脚本会启动项目的开发服务器,并可能还会运行一些其他的开发相关的任务,比如热更新代码、启动测试服务器等。在开发模式下,由于node会在后台做动态资源转发操作,所以一般不会产生跨域问题。
- npm run build是一个用于构建生产环境的命令。这个命令通常会运行一些脚本,这些脚本会打包你的项目,将所有的代码、资源文件压缩合并,然后输出到一个指定的目录中,这个目录通常是用于部署生产的。在生产环境下,由于没有node的动态资源转发操作,如果前后端分离项目中前端和后端的地址不同源,就会产生跨域问题。
指定文档目录
在config.mts指定文档目录为docs
export default defineConfigWithTheme({
srcDir: "docs",
})代码块常见编程语言
在 Markdown 或代码块语法中,语言名称用于指定代码的编程语言或格式,以便进行语法高亮。以下是常见的语言名称示例:
常见编程语言
| 语言名称 | 用途 | 示例代码块标记 |
|---|---|---|
python | Python 代码 | ```python |
javascript | JavaScript 代码 | ```javascript |
java | Java 代码 | ```java |
c | C 语言代码 | ```c |
cpp | C++ 代码 | ```cpp |
csharp | C# 代码 | ```csharp |
swift | Swift 代码 | ```swift |
ruby | Ruby 代码 | ```ruby |
php | PHP 代码 | ```php |
脚本与标记语言
| 语言名称 | 用途 | 示例代码块标记 |
|---|---|---|
html | HTML 标记 | ```html |
css | CSS 样式 | ```css |
xml | XML 数据 | ```xml |
markdown | Markdown 文本 | ```markdown |
json | JSON 数据 | ```json |
yaml | YAML 配置 | ```yaml |
数据与查询语言
| 语言名称 | 用途 | 示例代码块标记 |
|---|---|---|
sql | SQL 查询 | ```sql |
graphql | GraphQL 查询 | ```graphql |
mongodb | MongoDB 查询 | ```mongodb |
命令行与配置
| 语言名称 | 用途 | 示例代码块标记 |
|---|---|---|
bash | Bash 命令行脚本 | ```bash |
shell | Shell 命令 | ```shell |
dockerfile | Dockerfile 配置 | ```dockerfile |
nginx | Nginx 配置 | ```nginx |
其他格式
| 语言名称 | 用途 | 示例代码块标记 |
|---|---|---|
plaintext | 无语法高亮的纯文本 | ```plaintext |
diff | 差异对比文件 | ```diff |
latex | LaTeX 公式 | ```latex |
注意事项
- 大小写不敏感:大多数工具支持
python和Python。 - 工具兼容性:不同平台(如 GitHub、VS Code)支持的语言名称可能略有差异。
- 自定义别名:部分工具允许使用别名,例如:
js→javascriptpy→pythonyml→yaml
如果需要完整的支持列表,可以参考具体工具的文档(如 Prism.js 支持的语言)。
为博客增加鼠标点击特效-烟花
新建一个./theme/components/confetti.vue文件
TIP
组件代码
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import confetti from 'canvas-confetti';
// 定义触发烟花效果的函数
const triggerFireworks = (event: MouseEvent) => {
const x = event.clientX / window.innerWidth; // 鼠标点击的相对 X 坐标
const y = event.clientY / window.innerHeight; // 鼠标点击的相对 Y 坐标
// 配置烟花效果
confetti({
particleCount: 150, // 粒子数量,增加数量以增强效果
startVelocity: 5, // 初始速度,降低速度
spread: 360, // 扩散角度,360 度表示全方位扩散
origin: { x, y }, // 粒子的起始位置
gravity: 0.2, // 重力值,使粒子更轻盈
scalar: 0.8, // 粒子大小
ticks: 200, // 动画持续时间(帧数)
shapes: ["circle", "square", "star"], // 粒子形状
colors: ["#ff00ff", "#00ffff", "#ffff00", "#ff0000", "#00ff00", "#0000ff"], // 粒子颜色
drift: 0, // 粒子的水平漂移量
decay: 0.94, // 粒子速度衰减
});
// 添加上升的粒子效果
confetti({
particleCount: 30,
startVelocity: 10,
spread: 360,
origin: { x, y },
gravity: -0.2, // 负值使粒子向上飘动
scalar: 0.6,
ticks: 120,
shapes: ["square"],
colors: ["#ff0000", "#00ff00", "#0000ff"],
});
};
// 挂载时绑定全局点击事件
onMounted(() => {
document.addEventListener("click", triggerFireworks);
});
// 组件销毁时移除事件监听
onUnmounted(() => {
document.removeEventListener("click", triggerFireworks);
});
</script>:::
然后在index.ts中添加全局定义
Details
import { h } from 'vue'
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import './style.css'
import confetti from "./components/confetti.vue"
export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
},
async enhanceApp({ app, router, siteData }) {
// 注册全局组件transparent
app.component('confetti' , confetti),
}
} satisfies Theme最后在md中调用即可
Details
<!-- 爆炸效果 -->
<confetti />Vitepress插入live2d人物,为你的网页添加一个看板娘
.
docs
├─ .vitepress ->VitePress的配置目录
│ └─ config.mts ->定义网站的全局配置
│ └─ theme ->自定义主题
│ └─ index.mts 或者 index.ts ->定义主题的样式、布局和功能
├─ docs ->存放文档内容的主目录
│ ├─ index.md ->文档网站的首页文件
│ └─ public ->存放静态资源的目录
└─ node_modules ->Node.js项目中依赖模块的存储目录在你的VitePress项目中安装oh-my-live2d库
npm install oh-my-live2d@latest然后在.vitepress/theme/index.ts文件中添加以下代码
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme';
export default {
...DefaultTheme,
async enhanceApp() {
if (!import.meta.env.SSR) {
const { loadOml2d } = await import('oh-my-live2d');
loadOml2d({
models: [
{
path: 'https://cdn.jsdelivr.net/gh/Eikanya/Live2d-model/Live2D/Senko_Normals/senko.model3.json'
}
]
});
}
}
};在path路径中填写你的模型文件.model.json|.model3.json
loadOml2d参数解析
mobileDisplay:移动端人物展示开关(true|false)
models: {
path:本地|在线模型地址
position:人物位置
scale:人物缩放大小
stageStyle:舞台范围(width宽度height高度)
}
loadOml2d({
mobileDisplay: true,
models: [
{
"path": ['/ariu/ariu.model3.json',],
"position": [0, 60],
"scale": 0.08,
"stageStyle": {
"height": 500
}
},
{
"path": ['/豌豆射手/豌豆射手.model3.json',],
"position": [0, 60],
"scale": 0.16,
"stageStyle": {
"height": 400
}
}
]
});小纸条
本地模型文件要放在public文件夹下,支持多级搜索
小纸条
如果出现这个报错可不必理会,正常build就行。

live2d人物来源
以下列出此网站的live2d人物来源
【免费L2D模型】可盐可甜的机能风少女!无料模型大公开~点击领取-哔哩哔哩
【live2d免费模型】⚡️小黑子:过来吧我的辛苦奴隶⚡️-哔哩哔哩
网上开源的live2d人物模型库
[人物模型库]-(https://github.com/oh-my-live2d/live2d-models)
[狐狸]-(https://model.oml2d.com/Senko_Normals/senko.model3.json)
[小恶魔]-(https://model.oml2d.com/Pio/model.json)
[学生]-(https://model.oml2d.com/shizuku/shizuku.model.json)
[上班族]-(https://model.oml2d.com/shizuku_pajama/index.json)
创建你的专属空间
在你的./theme/components目录中创建PasswordCheck.vue文件
PasswordCheck.vue
<template>
<div v-if="!isLocked" class="password-protected">
<!-- 密码框和解锁按钮 -->
<div class="unlock-section">
<input
type="password"
v-model="password"
placeholder="请输入密码"
class="password-input"
/>
<button @click="checkPassword" class="check-button">✔️</button>
</div>
<!-- 提示信息 -->
<div v-if="showHint" class="hint-message" :class="{ fading: hintFading }">
前面的区域以后再来探索吧
</div>
<!-- 文档内容 -->
<transition name="fade">
<div v-if="isPasswordCorrect" class="document-content">
<!-- 这里插入你的 Markdown 内容或其他组件 -->
<slot></slot>
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
password: '',
isPasswordCorrect: false,
isLocked: false,
attempts: 0,
showHint: false,
hintFading: false,
};
},
methods: {
checkPassword() {
const correctPassword = '123'; // 改成你自己的密码
if (this.password === correctPassword) {
this.isPasswordCorrect = true;
} else {
this.attempts += 1;
alert('密码错误,请重试。');
if (this.attempts >= 1) {
this.showHint = true; // 显示提示信息
setTimeout(() => {
this.hintFading = true; // 开始渐隐
setTimeout(() => {
this.startDissolveAnimation(); // 开始分解消散动画
}, 2000); // 提示信息显示2秒后开始分解消散
}, 500); // 延迟0.5秒后开始渐隐
}
}
},
startDissolveAnimation() {
const dissolveElement = document.querySelector('.password-protected');
dissolveElement.style.animation = 'dissolve 2s forwards';
setTimeout(() => {
this.isLocked = true; // 动画结束后锁定大框
}, 2000); // 确保动画完成后再设置 isLocked
},
},
};
</script>
<style scoped>
.password-protected {
width: 100%; /* 框宽度与页面相同 */
margin: 2em auto;
padding: 1em;
border: 1px solid #ccc;
border-radius: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: linear-gradient(135deg, #ff7e5f, #feb47b); /* 渐变背景 */
color: white;
text-align: left; /* 修改为向左对齐 */
position: relative;
overflow: hidden;
transition: opacity 2s ease-out, transform 0.5s ease-out; /* 渐隐和上浮过渡 */
transform: translateY(0); /* 初始位置 */
}
@keyframes dissolve {
0% {
opacity: 1;
background: linear-gradient(135deg, #ff7e5f, #feb47b);
}
100% {
opacity: 0;
background: linear-gradient(135deg, rgba(255, 126, 95, 0), rgba(251, 180, 123, 0));
}
}
.password-protected:hover {
transform: translateY(-10px); /* 鼠标悬停时上浮 */
}
.unlock-section {
display: flex; /* 使用 flex 布局 */
align-items: center; /* 垂直居中 */
justify-content: flex-start; /* 水平起始对齐 */
}
.password-input {
width: calc(100% - 60px); /* 为按钮留出空间 */
padding: 10px;
margin-right: 10px; /* 与按钮的间距 */
border: 1px solid #ccc;
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.8); /* 输入框半透明 */
color: #333;
}
.check-button {
width: 40px; /* 设置按钮宽度 */
height: 40px; /* 设置按钮高度 */
padding: 0;
background-color: #05c10f;
color: white;
border: none;
border-radius: 10px; /* 圆角矩形 */
cursor: pointer;
transition: background-color 0.3s, transform 0.3s;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5em; /* 调整对号大小 */
}
.check-button:hover {
background-color: #369f7e;
transform: scale(1.05); /* 鼠标悬停时轻微放大 */
}
.document-content {
margin-top: 2em;
padding: 1em;
border: 1px solid #ccc;
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.8); /* 内容框半透明 */
color: #333;
transition: opacity 0.5s;
text-align: left; /* 修改为向左对齐 */
}
.hint-message {
margin-top: 1em;
padding: 1em;
background-color: rgba(255, 255, 255, 0.8); /* 提示框半透明 */
border: 1px solid #ccc;
border-radius: 10px;
text-align: left; /* 修改为向左对齐 */
transition: opacity 2s ease-out, filter 2s ease-out;
filter: blur(0); /* 初始无模糊 */
}
.hint-message.fading {
opacity: 0;
filter: blur(5px); /* 渐隐时模糊 */
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>然后,在index.ts中注册全局组件
/* .vitepress/theme/index.ts */
import DefaultTheme from 'vitepress/theme'
import Password from "./components/PasswordCheck.vue"
export default {
extends: DefaultTheme,
enhanceApp({app}) {
// 注册全局组件
app.component('Password' , Password)
}
}在你想加密的文档中添加这段代码
<Password>
markdown写作内容
</Password>自动获取网站图标
如何使用 Favicon.im 获取图标 使用 Favicon.im 非常简单,只需在网址后加上目标网站的域名即可获取该网站的 favicon 图标。
利用deepseek为你的博客锦上添花
prompt:
写一篇关于{}的技术博客
语言风格为严谨的专业性描述中加一点有趣的解释
公式格式为latex
frontmatter格式为
---
title: 标题
description: 简述
tags:
- 标签(可以叠加)
---通俗解释,使用有趣但不失严谨的比喻📖FAQS
代码块怎么默认显示行号?
在comfig.mts文件中添加lineNumbers:true,
export default defineConfigWithTheme({
markdown: {
lineNumbers:true,
}
})为什么我的Vitepress无法加载图床外链?
在config.mts的export default defineConfigWithTheme中添加以下代码
export default defineConfigWithTheme({
head: [
/* 解决了Vitepress无法加载图床链接的问题 */
[
"meta",
{
name:"referrer",
content:"no-referrer"
}
],
],
})为什么我的Katex总是重复渲染?
没有引入Katex的css文件,同时引入的css文件要对应版本,插件的github页面上有说明
export default defineConfigWithTheme({
head: [
['link', { rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css' }],
],
markdown: {
config: (md) => {
md.use(markdownItKatex),
},
},
vue: {
template: {
compilerOptions: {
isCustomElement: (tag) => customElements.includes(tag)
}
}
}
})Frontmatter是什么?
Frontmatter是md文件中最上方使用两个“---”框起来的YAML数据
---
title: 🥯从零开始的Vitepress博客网站搭建?
description: 使用Vitepress搭建个人博客时,需要归档和标签,利用createContentLoader进行生成
layout: doc
tags:
- vitepress
- 前端
- 闲谈
created: '2024-05-07'
updated: '2024-05-18'
---在原页面中引用
显示文本内容{{ $frontmatter.title }}在其他页面中引用
import { useData } from 'vitepress'
const { frontmatter, page } = useData()
显示文本内容{{ this.$frontmatter.title }}能用来干嘛?
- 设计标签页
- 更新时间记录
- 全局组件信息输入
