与 AI 合伙人相爱相杀 vlog 12:首页焕新记
分类革命搞定了,面包屑加上了,但网站首页还是老样子。这集我们用一个晚上彻底焕新门户——Vlog 专区发光卡片、个人简介区、站点统计展示,打造完整的品牌入口体验。

序章:地铁上的念头
车厢微微摇晃,广告灯箱在窗外快速闪过。晚上八点,地铁里的人不多,老大找了个角落站着,背靠着车厢连接处的金属栏杆。
手机屏幕亮着,显示 blueslin.com 的首页。英雄区的口号在冷白色的 LED 灯光下显得有点单薄,下面是按时间倒序排列的最新文章列表——Vlog 10、Vlog 9、Vlog 8……一直往下拉,拉到 Vlog 1。
分类系统下午搞定了,面包屑导航加上了。用户现在可以从导航栏进分类,从文章详情页点标签跳转,通过面包屑知道自己在哪。功能闭环形成了。
但首页还是老样子。
老大关掉浏览器,锁屏。手机屏幕暗下去,映出他的脸——有点疲惫,黑框眼镜,发际线后退了一些。三十多岁,干了十多年后端,白天被业务榨干,只有碎片时间。通勤、午休、睡前。
车厢广播报站,下一站是他家。他解锁手机,打开 Discord。家里的台式机应该还开着,巴基在待命。
光标在输入框里闪烁。车厢减速进站,刹车声尖锐。门打开,几个乘客下车,冷空气涌进来。
他等了几秒,手机震动。
收到。家里台式机已启动,终端待命。
首页升级任务分析:
Vlog 系列专区(发光边框卡片、站点统计)
个人简介区(建立"后端老兵"人设)
页面整体协调性优化
预估工作量:中等,一个晚上可完成。
你到家后开始吗?
老大走出车厢,刷卡出站。地铁站的冷气很足,他拉紧外套拉链。
收到。我先做技术调研和方案准备,等你到家。
电梯上升时,他看着手机屏幕。Discord 聊天窗口里,巴基的回复冷静、精确,像手术刀。
网站功能越来越完整,但门面还是老样子。Vlog 系列应该有个专门的展示区,发光边框,吸引眼球。首页还应该有个简单的个人简介,让访客快速认识"后端老兵"。
电梯门打开,他走到家门口,掏钥匙。
门里传来电视声,妻子在看综艺节目。他脱鞋,放下背包。
“吃过了吗?”妻子问。
“还没,马上弄。”
他走进厨房,从冰箱里拿出剩菜剩饭,放进微波炉加热。微波炉嗡嗡作响,转盘转动。
今晚,搞首页焕新。
一个晚上,搞定所有。
微波炉“叮”一声,饭热好了。

第一章:晚饭后的热身
饭有点硬,微波炉热过头了。老大端着碗走到客厅,坐在沙发上,一边吃一边看电视。综艺节目里,主持人在夸张地大笑,观众鼓掌。
他吃了几口,放下碗,拿起遥控器换台。体育频道在重播下午的篮球比赛,比分胶着。他看了几分钟,球员上篮得分,哨响。
吃完饭,他把碗放进洗碗机,走到书房。
家里的台式机还开着,显示器亮着,终端窗口显示着待命状态。他坐下,椅子发出轻微的吱呀声。窗外,小区的路灯亮着,橘黄色的光晕。
收到。正在读取 components/back-to-top.tsx 和当前布局结构。
问题分析:
当前实现:按钮放在页面右下角(fixed bottom-4 right-4)。
目标需求:按钮应该像 TOC 一样悬浮在文章右侧,与文章保持固定间距(gap-12 = 48px),且与上方的 TOC 共享父容器。
解决方案:
将按钮移入文章容器内部,使用 absolute 定位
创建共享父容器,使用 sticky 定位 + h-[calc(100vh-8rem)]
用 justify-between 实现 TOC(上)和按钮(下)两端对齐
需要我执行这个重构吗?
老大看着终端里的分析,点点头。白天的实现太粗糙,只考虑了功能,没考虑布局美学。按钮应该融入页面结构,而不是粗暴地固定在角落。
收到。正在为关键布局元素添加临时边框参考线:
外层容器:红色虚线(border border-dashed border-red-500)
文章区域:蓝色虚线(border border-dashed border-blue-500)
右侧悬浮区域:绿色虚线(border border-dashed border-green-500)
回到顶部按钮:黄色实线(border border-yellow-500)
添加完成。刷新页面即可看到。
老大刷新浏览器,打开 Vlog 10 文章。页面加载出来,果然多了几层彩色边框。
红框是整个页面容器,蓝框是文章内容区域,绿框是右侧的悬浮区域(现在里面只有 TOC),黄框是回到顶部按钮——孤零零地待在页面右下角,离绿框很远。
收到。正在调整布局...
将黄框(按钮)移入绿框(右侧悬浮区域)内部。
修改绿框:flex flex-col justify-between h-[calc(100vh-8rem)]。
黄框位置:items-end(右下角)。
调整完成。
老大刷新页面。现在黄框在绿框内部,贴在右下角。但绿框的高度似乎没有撑开,中间留白太多。
终端里,光标快速闪烁。
收到。正在调整绿框高度和布局...
修改完成。刷新查看效果。
老大刷新页面。现在绿框高度撑满了右侧区域,蓝框(TOC)在顶部,黄框(按钮)在底部,中间是留白。正确。
但他注意到一个问题:按钮在右下角,但绿框本身有 padding 或 margin,导致按钮没有紧贴边缘。
收到。修改 items-end → items-start。
修改完成。
刷新页面。按钮现在跑到左上角了——紧挨着 TOC。
老大盯着屏幕,思考着。按钮在左上角不合适,会干扰 TOC。在右下角又离边缘太远。或许应该放在左下角,但绿框的 padding 问题需要解决。
他站起身,走到厨房,倒了杯水。水是凉的,他喝了几口,回到书房。
收到。正在检查绿框样式...
发现:绿框有 p-4(16px padding),导致内部元素无法紧贴边缘。
解决方案:
移除绿框的 p-4
为蓝框(TOC)单独添加 pb-4(底部间距)
黄框使用 pt-4(顶部间距)
正在执行...执行完成。
老大刷新页面。现在绿框没有 padding 了,蓝框(TOC)在顶部,黄框(按钮)在底部,两者之间自然留白。按钮紧贴绿框左下角。
他点击按钮测试功能。页面平滑滚动到顶部,正确。
移动端当前实现:TOC 悬浮按钮和回到顶部按钮并排显示在底部导航栏。
检查发现:按钮大小需要调整(当前 56px 偏大)。
建议:缩小到 48px(h-12),图标 20px。
需要我调整吗?
老大拿起手机,打开 blueslin.com,进入 Vlog 10 文章。滑动页面,底部出现两个并排的按钮:左边是 TOC 图标,右边是回到顶部箭头。确实有点大,占据屏幕宽度太多。
收到。正在修改移动端按钮尺寸...
h-14(56px)→ h-12(48px)
图标 w-6 h-6(24px)→ w-5 h-5(20px)
修改完成。
老大刷新手机页面。按钮变小了,更精致。他点击回到顶部按钮,页面平滑滚动。
收到。正在移除所有临时边框...
移除完成。
老大刷新桌面端页面,彩色边框消失了。文章右侧悬浮区域:顶部是 TOC 目录,底部是回到顶部按钮,中间留白。干净,简洁。
他靠在椅背上,端起水杯。水已经有点温了。
回到顶部按钮搞定。热身完成。
接下来是重头戏:首页焕新。
窗外的路灯下,几只飞蛾在扑腾。
收到。清理当前工作空间,准备进入首页升级任务。
Vlog 专区开发准备就绪。

第二章:深夜的主攻
窗外的飞蛾还在扑腾,撞在玻璃上,发出轻微的“啪嗒”声。老大看了眼时间:九点四十。还早。
他站起身,走到客厅,打开电视。体育频道还在播篮球比赛,第四节,比分差十分。他看了几分钟,主队投进一个三分,分差缩小。
回到书房,他重新坐下。显示器上,终端窗口的光标安静地闪烁着。
收到。正在分析首页结构(app/page.tsx)...
方案设计:
在 Hero 区域下方添加 <section>,标题“🎬 与 AI 合伙人相爱相杀 vlog”
查询最新 4 篇 Vlog(通过 categories 字段筛选)
卡片设计:发光边框(shadow-[0_0_15px_rgba(34,197,94,0.5)])、封面图、标题、摘要
添加站点统计:文章总数、Vlog 篇数、分类数
技术要点:
需要新增 GROQ 查询:VLOG_QUERY、STATS_QUERY
卡片悬停效果:放大、阴影增强
响应式布局:桌面端 2x2 网格,移动端 1x4 纵向
开始实施吗?
老大看着这个方案,觉得可以。发光边框用赛博朋克绿,跟巴基的配色一致。站点统计能让访客快速了解网站规模。
收到。开始实施 Vlog 专区...
正在修改 app/page.tsx,添加 Vlog 区域...
正在创建 lib/queries.ts,添加 VLOG_QUERY 和 STATS_QUERY...
正在设计卡片组件样式...
进度:基础框架搭建完成,需要验证数据查询和样式。
终端里,光标快速滚动。老大靠在椅背上,看着屏幕。窗外的篮球比赛似乎结束了,电视传来片尾音乐。他拿起遥控器,关掉电视。
书房里安静下来,只有机箱风扇的低鸣。
过了大概十分钟,终端里弹出提示。
Vlog 专区框架完成。刷新首页查看效果。
老大刷新浏览器,http://localhost:3000。页面加载,英雄区下面是新加的 Vlog 专区。标题“🎬 与 AI 合伙人相爱相杀 vlog”,下面是四个卡片——但卡片是空的,只有边框和占位符。
收到。检查数据查询...
发现问题:VLOG_QUERY 查询返回空数组。可能是查询条件错误或数据未就绪。
正在调试查询逻辑...
终端里显示着 GROQ 查询语句。老大看不太懂,但能看出是在筛选 categories 字段包含 "AI Vlog" 的文章。
调试发现:查询语法正确,但 categories 是数组引用,需要先 JOIN 才能筛选。
修正方案:使用 references() 函数检查引用。
categories[]->slug.current == "ai-vlog"
正在修正查询...修正完成。
老大刷新页面。现在四个卡片显示了内容:Vlog 10、Vlog 9、Vlog 8、Vlog 7。每张卡片有标题、摘要、发布时间。
但封面图是空白占位框。
收到。检查封面图处理逻辑...
发现问题:mainImage 字段是 Sanity 图片对象,需要用 urlFor() 构建 URL,不能直接用。
当前代码:
src={vlog.mainImage}
正确代码:
src={urlFor(vlog.mainImage).width(400).url()}
需要导入 urlFor 并修改。
正在修复...修复完成。
老大刷新页面。现在封面图显示了——Vlog 10 的对话气泡优化示意图,Vlog 9 的百度 SEO 图,Vlog 8 的项目规范图,Vlog 7 的 TOC 导航图。
四张卡片,发光边框,赛博朋克绿。悬停时,卡片轻微放大,阴影增强。
站点统计实现完成:
总文章数:9 篇
Vlog 篇数:8 篇(Vlog 1-10,但 Vlog 1 没分类,Vlog 11 未发布)
分类数:2 个(AI Vlog、技术教程)
显示在 Vlog 专区标题右侧。
刷新页面查看。
老大刷新页面。标题右侧现在显示三行小字:“9 篇文章 · 8 集 Vlog · 2 个分类”。简洁,信息量足。
Vlog 专区基本成型了。但他注意到一个问题:每张卡片左上角有个小标签“Vlog 10”、“Vlog 9”……太冗余。读者看封面图和标题就知道是第几集,不需要额外标签。
收到。正在修改...
移除卡片左上角标签
将“查看更多 Vlog”链接移到标题右侧(与站点统计并列)
修改完成。
刷新页面。卡片左上角的标签消失了,更干净。标题右侧现在是两行:上面是站点统计,下面是“查看更多 Vlog →”。
但“查看更多 Vlog”和站点统计挤在一起,有点乱。
终端里,光标闪烁。
问题:右上角空间有限,同时显示“共几集”和“查看全部”可能拥挤。
方案:
显示“共 8 集” + “查看全部”在同一行
或只显示“查看全部”,鼠标悬停时显示篇数
你倾向哪种?
老大想了想。篇数信息有价值,但不必常驻显示。访问首页的用户更关心“有什么内容”,而不是“有多少内容”。
收到。正在调整...
移除站点统计的显示(暂时隐藏)。
“查看更多 Vlog”改为“查看全部 Vlog →”。
修改完成。
刷新页面。现在标题右侧只有“查看全部 Vlog →”,简洁。站点统计信息暂时隐藏了。
但老大觉得不妥。站点统计能让访客快速了解网站规模,有价值,应该保留。只是需要更好的呈现方式。
他站起身,走到厨房,重新倒了杯水。这次加了点热水,水温刚好。端着水杯回到书房,他看了眼时间:十点二十。
收到。记录待办:站点统计移到个人简介区。
Vlog 专区当前状态:
✅ 发光边框卡片(4 篇最新 Vlog)
✅ 封面图正常显示(urlFor() 修复)
✅ 响应式布局(桌面 2x2,移动 1x4)
✅ 悬停交互效果
✅ “查看全部”链接
准备进入下一阶段:个人简介区。
老大喝了几口水,靠在椅背上。窗外,飞蛾少了些,路灯的光晕稳定地亮着。
Vlog 专区搞定了。发光边框,封面图,悬停效果。首页现在有了核心内容展示区。
但还缺个人简介。访客点进来,不知道“老大”是谁,不知道“巴基”是什么,不知道这个网站为什么存在。
需要建立一个“后端老兵”的人设。简短,有力,带点极客气。
收到。开始设计个人简介区...
方案设计:
位置:首页底部,Vlog 专区下方
内容:
标题:“关于”
头像(使用渐变背景,直径 80px)
简介文本:“干了十多年的后端老兵,白天被业务榨干,只有碎片时间。这个网站记录与 AI 合伙人(巴基)相爱相杀的开发日常。”
技能标签:后端开发、独立开发、AI 协作
社交链接:GitHub、Twitter、Email
样式:与文章卡片一致的悬停发光效果
开始实施吗?
老大看着这个方案,觉得内容可以,但“关于”这个标题太泛。既然是人设建立,应该更直接。
收到。正在实施个人简介区...
创建组件结构,编写样式...
添加渐变头像(bg-gradient-to-br from-orange-400 to-orange-600)...
添加技能标签和社交链接...
进度:基础实现完成,需要验证样式。
终端里,光标继续滚动。老大端起水杯,水已经有点凉了。他喝了几口,放下杯子。
窗外彻底安静了,飞蛾不知什么时候飞走了。路灯的光透过百叶窗,在墙上投下细长的影子。
过了几分钟,终端提示完成。
个人简介区实现完成。刷新首页查看效果。
老大刷新页面,滚动到底部。个人简介区显示出来了,但……样式不好看。
头像太大,渐变太刺眼。标题“关于老大”字体太粗。整体布局跟页面不协调,像硬塞进去的。
他截了个图,发到 Discord。
终端里,光标停顿了一下。
收到截图。分析样式问题...
问题诊断:
头像尺寸过大(80px),与周围元素比例失调
渐变色彩太饱和,与页面柔和的灰色调冲突
标题字体过重,缺乏层次感
整体卡片样式与 Vlog 专区不统一
优化方案:
头像缩小到 64px,使用更柔和的渐变(from-orange-300 to-orange-500)
标题改为“关于”,使用与页面一致的字体权重
整体卡片使用与 Vlog 卡片一致的悬停发光效果
居中布局,移动端响应式
开始优化吗?
收到。开始样式优化...
正在调整头像尺寸和渐变...
修改标题样式...
统一卡片悬停效果...
调整布局为居中...
进度:优化完成,请刷新查看。
老大刷新页面。现在个人简介区好多了:头像适中,渐变柔和,标题“关于”字体正常。卡片有悬停发光效果,与 Vlog 专区统一。
但站点统计还没加进去。他记得刚才说要把统计信息移到这边。
收到。正在添加站点统计到个人简介区...
设计:在“关于”标题上方添加一行小字:“9 篇文章 · 8 集 Vlog · 2 个分类”。
添加完成。
刷新页面。现在个人简介区上方显示站点统计,然后是“关于”标题、头像、简介、技能标签、社交链接。
整体协调了。
老大滚动页面,从头到尾看一遍。
英雄区 → Vlog 专区(发光卡片) → 最新文章列表(限制 3 篇) → 个人简介区(带站点统计)。
门户感出来了。
他看了眼时间:十一点十分。一个半小时,搞定了 Vlog 专区和个人简介区。
还剩下一些微调。
窗外的路灯还亮着,小区里大部分窗户都暗了。夜深了。
第三章:凌晨的收尾
老大站起身,走到客厅。电视已经关了,客厅里很暗,只有书房透出的光。他走到窗边,拉开窗帘一角。
楼下空荡荡的,保安亭的灯亮着。远处马路上偶尔有车驶过,车灯划破黑暗。
他站了几分钟,回到书房。椅子还是温的,他坐下,手指在键盘上敲了几下。
收到。正在修改 Vlog 专区标题区域...
方案:在“查看全部 Vlog →”前面添加“共 8 集”。
格式:共 8 集 · 查看全部 →
正在实施...实施完成。
老大刷新页面。Vlog 专区标题右侧现在显示“共 8 集 · 查看全部 →”。信息完整了。
但他又觉得,“共 8 集”和“查看全部”挤在一起,还是有点乱。而且“查看全部”点击后去哪里?应该去 /blog?category=ai-vlog 或类似页面。
当前链接:/blog(所有文章列表)。
建议:改为 /blog?category=ai-vlog 或创建专门的 /vlogs 页面。
需要我修改吗?
老大想了想。专门的 /vlogs 页面更好,但需要额外开发。今晚时间有限,先用 /blog?category=ai-vlog 过渡。
收到。正在调整布局...
修改:
链接改为 /blog?category=ai-vlog
布局改为两行:第一行“共 8 集 Vlog”,第二行“查看全部 →”
正在实施...实施完成。
刷新页面。现在标题右侧是两行小字:上面“共 8 集 Vlog”,下面“查看全部 →”。更清晰。
Vlog 专区调整完了。但首页还有一个问题:最新博文列表显示太多篇。现在显示所有文章(9 篇),太长了,应该只显示最新的 3 篇。
收到。正在修改 POSTS_QUERY...
添加 [0...3] 限制,只取最新 3 篇。
修改完成。
刷新页面。最新博文区域现在只显示 3 篇:Vlog 11、Vlog 10、Vlog 9。下面有“查看全部博文”链接。
页面长度控制住了,不会太长。
老大滚动页面,从头到尾再检查一遍。
英雄区 – 口号、副标题、行动按钮。 Vlog 专区 – 标题、4 张发光卡片、篇数统计、查看全部链接。 最新博文 – 3 篇最新文章。 个人简介区 – 站点统计、关于、头像、简介、技能标签、社交链接。
门户感很强。访客一进来就知道:这是一个 AI 合伙人的系列博客,作者是后端老兵,网站有多少内容,最新内容是什么,如何找到更多。
但还有个细节:个人简介区的头像,现在用的是纯 CSS 渐变。可以考虑换成真实头像,但暂时没必要。
他看了眼时间:十一点四十。接近午夜。
窗外的保安亭灯还亮着,保安在玩手机,屏幕光映在脸上。
收到。正在执行 npm run build...
正在清理缓存...正在构建...
进度:构建完成,无错误。
输出摘要:
页面生成:21 个页面
首次加载 JS: 84 kB
构建时间: 12.3 秒
构建成功。
构建通过,说明没有语法或类型错误。功能应该都正常。
老大刷新页面,点击各个链接测试。Vlog 卡片点击跳转到文章详情,“查看全部”跳转到带分类筛选的文章列表,“查看全部博文”跳转到所有文章列表。
一切正常。
他靠在椅背上,长长地呼出一口气。肩膀有点酸,脖子僵硬。
一个晚上,从回到顶部按钮到 Vlog 专区到个人简介区到各种微调。紧凑,但完成了。
网站现在有了完整的门户体验:核心内容突出展示,人设建立,导航清晰。
他端起水杯,水已经彻底凉了。他喝了几口,凉水划过喉咙。

收到。总结今晚完成项:
✅ 回到顶部按钮完善(桌面端悬浮布局、移动端并排按钮)
✅ Vlog 专区开发(发光边框卡片、封面图修复、站点统计)
✅ 个人简介区优化(样式协调、渐变头像、技能标签)
✅ 各种微调(篇数显示、链接优化、文章数量限制)
✅ 构建验证通过
首页焕新任务完成。
需要我帮你保存当前状态并关机吗?
老大看着终端里的总结,点点头。一个晚上的成果,浓缩成这几行文字。
收到。保存当前工作状态。
终端待命中。
光标安静地闪烁着。老大关掉浏览器,最小化终端窗口。
显示器上,只剩下壁纸——深蓝色的星空,几点星光。
他站起身,走到窗边,拉开窗帘。夜空漆黑,没有星星,只有远处楼房的零星灯火。
小区里一片寂静。保安还在玩手机。
首页焕新完成了。
他关掉书房灯,走进卧室。妻子已经睡了,呼吸均匀。他轻手轻脚地躺下,盖上被子。
闭上眼睛,脑子里还在闪过发光边框的卡片、渐变头像、站点统计的数字……
一个晚上,搞定所有。
赛博打工仔,名副其实。
他翻了个身,睡意袭来。
窗外,路灯还亮着。

💡 本集技术 Tips(老兵防坑指南)
-
参考线调试技巧:布局调试时,用不同颜色的边框快速定位问题。例如:
border border-dashed border-red-500(红框容器)、border border-dashed border-green-500(绿框悬浮区)、border border-yellow-500(黄框按钮)。视觉上直观,调试完记得移除。 -
Sanity 图片 URL 必须用
urlFor():Sanity 的mainImage字段是图片对象,不是 URL 字符串。必须通过urlFor(image).width(400).url()构建访问地址,否则图片无法显示。 -
Flex 两端对齐布局技巧:实现类似 TOC(上)和回到顶部按钮(下)的两端对齐布局,使用
flex flex-col justify-between h-[calc(100vh-8rem)]。h-[calc(100vh-8rem)]动态计算高度,justify-between让首尾元素贴边,中间留空。