ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

360小时从零到一:用Vue3+Nuxt3打造开箱即用的开源博客系统TaoToken实践

360小时从零到一:用Vue3+Nuxt3打造开箱即用的开源博客系统TaoToken实践 1. 为什么我选择用 Nuxt3 重写个人博客从零到一的开源博客系统踩坑记录独立开发者做个人博客最怕的不是写文章而是折腾环境。我最早用 Hexo静态生成快是快但每次想加个评论、搜索、后台管理就得装一堆插件主题改起来像在拆炸弹。后来换 WordPress功能全了可服务器成本、安全补丁、插件冲突又成了新负担。直到我把目光投向 Vue3 Nuxt3 这套组合才真正找到「开箱即用」和「可深度定制」之间的平衡点。这次我参考的开源项目是 flygoose飞鹅一款基于 Nuxt3 Vue3 TypeScript 的博客系统后端用 Golang MySQL。它的前端部分对前端开发者极其友好目录结构清晰SEO 友好而且自带后台管理、Markdown 编辑器、响应式布局。我花了大约 360 小时从零到一跑通整套流程这篇文章就把项目初始化、目录设计、本地启动验证以及如何通过 TaoToken 统一接入 AI 能力的完整步骤拆给你看。目标很明确你跟着做就能在本地跑起来一个属于自己的开源博客系统并且知道每一处配置为什么这么写。适合谁如果你熟悉 Vue3 基础想学 Nuxt3 的最佳实践或者想快速搭建一个能写文章、能管理内容、能接入 AI 辅助写作的独立站点那这篇内容就是为你准备的。我不会只贴代码还会解释每个文件的作用以及我踩过的坑。2. 飞鹅 flygoose 项目初始化与 Nuxt3 目录结构设计实战2.1 环境准备与项目拉取先确认本地环境Node.js 建议 18.x 或 20.x包管理器用 pnpm 或 npm 都行。我实测下来 pnpm 在 Nuxt3 项目里安装依赖更快磁盘占用也小。先拉取 flygoose 的前端仓库git clone https://github.com/helloworld-Co/flygoose-blog.git cd flygoose-blog pnpm install如果仓库结构是前后端分离的前端通常在web或frontend目录下。进入前端目录后你会看到典型的 Nuxt3 结构flygoose-blog/ ├── assets/ ├── components/ ├── composables/ ├── layouts/ ├── middleware/ ├── pages/ ├── plugins/ ├── public/ ├── server/ ├── stores/ ├── nuxt.config.ts ├── app.vue └── package.json这个结构不是随便定的。pages负责路由components放可复用 UIcomposables封装组合式函数server目录可以写 Nitro 服务端接口。flygoose 把博客前台和后台管理都放在同一个 Nuxt3 应用里通过路由区分这样部署时只需要一个 Node 服务省事。2.2 nuxt.config.ts 关键配置逐行解读nuxt.config.ts是整个项目的控制中心。我挑几个和博客系统强相关的配置说明export default defineNuxtConfig({ devtools: { enabled: true }, modules: [ nuxtjs/tailwindcss, pinia/nuxt, vueuse/nuxt, ], runtimeConfig: { public: { apiBase: process.env.NUXT_PUBLIC_API_BASE || http://localhost:8080/api, taoTokenBase: process.env.NUXT_PUBLIC_TAOTOKEN_BASE || https://taotoken.net/api, }, }, app: { head: { title: 飞鹅博客, meta: [ { name: description, content: 基于 Nuxt3 的开源博客系统 }, ], }, }, nitro: { preset: node-server, }, })这里有几个点值得注意。runtimeConfig.public里的变量会暴露给客户端所以不要放密钥。apiBase指向后端 Golang 服务的地址本地开发时通常是http://localhost:8080/api。taoTokenBase是我为了接入 AI 能力预留的后面会详细讲。nitro.preset设为node-server方便你部署到自己的服务器或容器里。2.3 目录结构设计背后的思考flygoose 的composables目录里通常会有useApi.ts、useAuth.ts这类文件。useApi封装了$fetch统一处理请求头、错误码和 baseURL。这样做的好处是当你要切换后端地址或加统一鉴权时只改一个文件。stores目录用 Pinia 管理全局状态比如用户登录信息、博客配置、主题色。middleware里可以写路由守卫比如后台管理页面需要登录才能访问。plugins目录适合放一些初始化逻辑比如全局注册组件或初始化第三方 SDK。我建议你在跑通项目后先花半小时把pages目录下的路由结构看一遍。通常会有index.vue首页、article/[id].vue文章详情、admin/后台管理等。理解路由结构后你改页面或加功能会快很多。3. 可复制的 Nuxt3 脚手架配置与 TaoToken 统一 Key 接入3.1 本地环境变量配置在项目根目录创建.env文件写入以下内容NUXT_PUBLIC_API_BASEhttp://localhost:8080/api NUXT_PUBLIC_TAOTOKEN_BASEhttps://taotoken.net/api TAOTOKEN_API_KEY你的TaoToken密钥注意TAOTOKEN_API_KEY没有NUXT_PUBLIC_前缀所以它只在服务端可用不会打包到客户端代码里。这是安全底线。如果你需要在客户端直接调用 AI 接口建议通过 Nuxt3 的server/api目录写一个代理接口把密钥留在服务端。3.2 在 Nuxt3 中封装 TaoToken 请求在server/api下新建ai/chat.post.tsexport default defineEventHandler(async (event) { const config useRuntimeConfig() const body await readBody(event) const response await $fetch(${config.public.taoTokenBase}/v1/chat/completions, { method: POST, headers: { Authorization: Bearer ${process.env.TAOTOKEN_API_KEY}, Content-Type: application/json, }, body: { model: body.model || gpt-4o-mini, messages: body.messages, temperature: 0.7, }, }) return response })这个接口的作用是前端调用/api/ai/chatNuxt3 服务端再转发到 TaoToken 的 API。这样做的好处是密钥不暴露而且你可以统一加日志、限流、缓存。3.3 前端调用示例在composables/useAi.ts里封装一个组合式函数export const useAi () { const chat async (messages: Array{ role: string; content: string }) { return await $fetch(/api/ai/chat, { method: POST, body: { messages }, }) } return { chat } }然后在文章编辑页面里你可以加一个「AI 润色」按钮调用chat方法把当前 Markdown 内容传进去让模型帮你优化表达。这就是「开箱即用」的 AI 能力接入。3.4 配置片段汇总如果你用的是 Cline 或 Claude Code 这类工具需要配置 Base URL、Key 和 Model ID可以参考{ baseUrl: https://taotoken.net/api, apiKey: 你的TaoToken密钥, modelId: gpt-4o-mini }如果你用 Codex 的auth.json格式类似{ api_key: 你的TaoToken密钥, base_url: https://taotoken.net/api }注意TaoToken 的 API 地址是https://taotoken.net/api不要加多余的路径。模型 ID 根据你实际使用的模型填写比如gpt-4o-mini、claude-3-5-sonnet等。4. 本地启动验证与成功结果确认4.1 启动后端服务flygoose 的后端是 Golang MySQL。如果你只想跑前端可以先把NUXT_PUBLIC_API_BASE指向一个 mock 服务或者用项目自带的 mock 数据。但为了完整验证建议把后端也跑起来。后端通常需要配置 MySQL 连接、Redis 连接然后执行go run main.go。4.2 启动前端pnpm dev终端会输出Nuxi 3.x.x Local: http://localhost:3000打开浏览器访问http://localhost:3000你应该能看到博客首页。如果首页有文章列表、分类、搜索框说明前端启动成功。如果页面空白或报错先看浏览器控制台和终端日志。4.3 验证 AI 接口在浏览器控制台或通过 curl 测试curl -X POST http://localhost:3000/api/ai/chat \ -H Content-Type: application/json \ -d {messages:[{role:user,content:你好}]}如果返回类似{ choices: [ { message: { role: assistant, content: 你好有什么可以帮你的吗 } } ] }说明 TaoToken 接入成功。如果返回 401检查TAOTOKEN_API_KEY是否正确如果返回local proxy failed检查网络或 Base URL 是否写错。4.4 成功结果确认清单首页能正常渲染文章列表点击文章能进入详情页后台管理页面能登录如果后端已启动AI 润色按钮能返回模型结果移动端响应式布局正常5. 本篇常见错误排查401、local proxy failed、reading choices、OAuth5.1 401 Unauthorized这是最常见的错误。原因通常是 API Key 没传、传错、或者 Key 已失效。检查.env文件里的TAOTOKEN_API_KEY是否和 TaoToken 控制台里的一致。如果你用的是server/api代理确认process.env.TAOTOKEN_API_KEY能被读取到。Nuxt3 在开发模式下会自动加载.env但如果你改了.env后没重启 dev server需要重启。5.2 local proxy failed这个报错通常出现在你用了本地代理工具但代理配置和 TaoToken 的 Base URL 冲突。TaoToken 的 API 地址是https://taotoken.net/api不需要额外代理。如果你本地有全局代理尝试把taotoken.net加入直连列表。另外检查NUXT_PUBLIC_TAOTOKEN_BASE是否写成了https://taotoken.net/api/末尾多了斜杠有些 HTTP 客户端对斜杠敏感。5.3 reading choices 报错这个错误一般发生在解析 AI 响应时。TaoToken 返回的 JSON 结构里choices是一个数组。如果你在代码里直接写response.choices[0].message.content但实际返回的choices为空就会报Cannot read properties of undefined (reading choices)。解决办法是加一层判断if (!response.choices || response.choices.length 0) { throw new Error(AI 返回结果为空) }另外有些模型在流式输出时choices的结构不同需要按流式格式解析。5.4 OAuth 相关错误如果你在接入 Claude Code 或类似工具时遇到 OAuth 报错通常是因为认证方式选错了。TaoToken 的 API 使用 Bearer Token 认证不需要 OAuth 流程。在 Claude Code 的配置里选择 API Key 模式填入 TaoToken 的 Key 和 Base URL 即可。如果你看到OAuth token invalid检查是否误用了 OAuth 配置。5.5 其他坑端口冲突Nuxt3 默认 3000如果被占用用pnpm dev --port 3001。依赖版本Nuxt3 生态更新快如果pnpm install后报错尝试删除node_modules和pnpm-lock.yaml重新安装。环境变量不生效Nuxt3 的runtimeConfig在构建时和运行时行为不同确保你用的是process.env而不是import.meta.env。6. 从本地到线上TaoToken 统一通道的长期编码与 Agent 实践跑通本地后你可能会想把这个博客部署到线上或者用 AI 辅助写文章、自动生成摘要、甚至做一个博客问答机器人。这时候 TaoToken 的统一 Key/API 通道就体现出价值了你不需要为每个模型单独申请 Key也不需要改代码里的 Base URL只需要在.env里换一个 Key就能切换模型。如果你长期做编码或 Agent 开发可以关注 TaoToken 的 Coding Plan它适合需要频繁调用模型、做代码补全、自动化任务的场景。模型对话入口适合快速验证模型效果API Keys 页面可以管理你的密钥接入文档里有详细的参数说明。我自己的做法是在博客后台加一个「AI 助手」面板用 TaoToken 的 API 做三件事——文章摘要生成、标签推荐、评论情感分析。这样既提升了写作效率也让博客有了智能化的交互体验。你不需要一次做完先跑通一个接口再逐步扩展。最后提醒一句所有配置里的 Base URL 统一用https://taotoken.net/api不要加 UTM 参数到 API 地址里。密钥不要提交到 Git 仓库用.gitignore把.env排除掉。如果你在部署时遇到问题先检查服务端能否访问外网再检查密钥权限。
返回列表