Vibe Coding了一个“朋友圈”
记录用 Vibe Coding 开发朋友圈动态的过程,与其说是朋友圈,不如说是个人动态。
背景
博客适合写完整内容,比如某个技术点、某次折腾记录、年度总结之类。可平时经常会有一些很零碎的想法,只想简单发一句话、一张图、一个链接,如果专门写成文章又太重,最后大概率就是不写了。
所以就想在网站里加一个类似朋友圈的功能,随手记录一些动态,让这个网站看起来不只是一个文章列表,而是一个更接近日常的个人空间。
这篇文章就简单记录一下这个功能从想法到上线的过程,也算是我第一次比较完整地用 Vibe Coding 写一篇功能开发记录。
为什么做朋友圈动态
其实动机挺简单,主要还是想降低记录成本。
之前写博客会有一种心理负担,一篇文章总得有个主题,有开头有结尾,最好还能讲清楚来龙去脉。但动态就不一样,想到什么就发什么,不需要太完整,也不用非得总结出什么结论。
另外就是现在很多内容都会发在社交平台,但发完之后就散落在各个平台里了。既然已经有自己的站点,那不如把这些轻量内容也放在自己这里,后续回看也方便。
还有一点是想试试 Vibe Coding 能把一个完整功能推进到什么程度。朋友圈动态看起来只是一个列表,但真做起来会涉及发布、图片、点赞、评论、权限、分页、缓存、通知等一堆细节,刚好适合拿来实践。
先做一个能跑的版本
一开始并没有想得特别复杂,目标就是先把最小闭环跑通:能发布,能保存,能展示。
页面入口放在 /pyq,页面主要由 PostCover 和 PostList 两部分组成。PostCover 负责顶部封面和发布入口,PostList 负责动态流展示。
数据这块用的是 Supabase,主要是图省事,数据库和图片存储都能一起解决。表结构也比较直接:
pyq_users用户信息pyq_posts动态内容pyq_likes点赞pyq_comments评论pyq_admin_read_at管理员已读记录
第一版只要能把动态发出来,其实就已经有点感觉了。
很多功能都是在这个基础上慢慢加的,这点跟一开始想象的不太一样。原本以为做个动态流应该很快,结果越做越发现,朋友圈这种看起来很轻的功能,背后全是细节。
动态流不是简单列表
最开始的动态流确实只是简单列表,按创建时间倒序展示。
跑起来之后发现,如果内容多了,只是一直往下排会有点乱,看不出时间感。所以后面又加了按月份分组,普通动态按月份归类,月份标题固定在列表里,看起来更像时间线。
置顶动态也单独处理了。因为置顶内容不太适合混在月份分组里,不然既要保持置顶,又要参与时间线排序,逻辑会有点别扭。最后的处理方式是置顶动态单独返回,普通动态再走分页和月份分组。
触底加载用的是 IntersectionObserver,滚动到底部自动请求下一页。动态流还是更适合这种交互,不需要用户去点分页按钮。
这里也能感受到 Vibe Coding 的节奏:先让列表出来,再根据真实页面感觉调整。很多时候盯着代码想半天,不如先跑起来看一眼。
图片上传
发布动态支持文字和图片,图片上传到 Supabase Storage,动态里保存图片地址。
上传本身还好,真正容易忽略的是删除。
一开始很容易只想着删数据库记录,但图片已经传到 Storage 了,如果不一起删,时间久了就会留下一堆没人引用的文件。所以删除动态时,也要同步把对应图片清掉。
编辑动态也有类似问题,如果图片发生变化,就要考虑旧图片怎么处理。这个地方不是一开始就设计完整的,而是写着写着发现边界越来越多。
实际做这种功能经常就是这样:第一版先能用,然后再把这些边角补上。要是从一开始就把所有情况都想完,估计功能还没写就先累了。
点赞和评论
朋友圈没有点赞和评论总感觉差点意思,所以后面又补了这两块。
点赞相对简单,点一下请求接口,再更新当前状态。评论稍微麻烦一点,因为评论列表没必要首屏全部加载,尤其动态多了以后会影响性能。
这个问题也是实际用的时候才明显感觉到的。如果每条动态都带着评论一起请求,首屏会做很多没必要的事情。大部分时候用户只是先浏览动态,不一定会展开评论。
最后的处理方式是评论区域懒加载,动态卡片进入可视区域附近时再请求评论。这样首屏只关注动态本身,评论等用户真正看到时再加载。
这类优化单独看都不难,但很难在第一天就全想出来。页面跑起来之后,哪里慢、哪里别扭、哪里多余,才会变得很明显。
公开和私有
做个人动态时会遇到一个问题:有些内容适合公开,有些只想自己记录。
所以动态加了 public 和 private 两种可见性。普通访问者只能看到公开动态,管理员可以看到全部内容。
这个功能对我来说挺重要,因为它让朋友圈动态不只是一个公开展示页,也可以当成自己的轻量记录工具。有些内容没必要给所有人看,但又不想另外找地方记。
管理员相关操作包括发布、编辑、删除、置顶、查看私有动态等。接口层会校验管理员密码,校验通过后才返回完整数据。
权限这类东西还是要谨慎一点,AI 可以帮忙写接口,但哪些数据能返回、哪些操作必须校验,还是得自己盯着。
通知是后来才加的
一开始其实没打算做通知。
评论功能做好之后才发现,如果没人提醒,我自己也不一定知道有人评论了动态。于是又加了通知 banner、历史记录和已读状态。
到这一步,朋友圈动态已经不只是一个展示页面了,基本有了简单后台的感觉。虽然没有单独做后台页面,但发布、编辑、删除、置顶、通知这些能力都在页面里完成了。
这也是这类功能容易“长出来”的地方。你以为只是加个评论,评论加完又会自然想到通知;通知有了又要有已读;有已读又要能看历史。功能之间会互相牵引。
首屏缓存
动态流最明显的优化是首屏缓存。
使用 sessionStorage 保存一份 feed 快照,再次进入页面时可以先展示缓存内容,然后再请求最新数据。缓存带了版本号和过期时间,避免后续数据结构变化导致旧缓存出问题。
这个优化对体验提升挺明显,尤其是从其他页面返回动态页时,不会一直空白等接口返回。
一开始没做缓存时,页面不是不能用,但会有一点“等一下”的感觉。加了缓存之后,至少视觉上会更连贯。
Vibe Coding 的感受
这次开发很明显感受到 Vibe Coding 的优势:不用一开始就把所有细节想完,可以先描述一个大概方向,然后快速得到一个能跑的版本。
比如最开始只是“做一个朋友圈动态”,跑起来后发现需要分页;分页有了之后发现需要缓存;评论有了之后发现需要通知;图片能上传后又要考虑删除清理。
很多需求不是提前设计出来的,而是在使用过程中冒出来的。
以前写这种功能,我可能会先纠结表怎么设计、组件怎么拆、接口怎么分。现在更多是先把需求描述清楚,让 AI 起一版,我再根据页面效果一点点改。
但也不能完全放手。AI 有时候会把简单问题写复杂,也会漏掉一些只有实际使用才会发现的边界,比如图片删除、评论加载、管理员视角这些。它更像是把实现速度提上来,但最终方向和取舍还是要自己判断。
这次最明显的感受是:Vibe Coding 不是让人不思考,而是让试错成本变低。想法可以很快变成页面,然后再根据真实体验继续修。
开发结果
目前朋友圈动态已经包含这些能力:
- 发布图文动态
- 动态列表展示
- 置顶动态
- 按月份分组
- 触底加载更多
- 点赞
- 评论
- 图片上传和删除
- 公开 / 私有动态
- 管理员编辑和删除
- 评论通知和历史记录
- 首屏缓存
技术上主要用到:
- Next.js App Router
- Route Handlers
- Supabase
- React Query
从结果看,它已经不是一开始想的“加个动态列表”了,而是一个围绕个人记录展开的小型动态系统。
总结
这次开发朋友圈动态,最开始只是想给博客加一个轻量记录入口,最后做着做着变成了一个完整功能。
博客适合沉淀,动态适合记录当下。对我来说,这个功能补上了个人网站里比较生活化的一块。
通过这次实践,对 Vibe Coding 的感受也更明确了:它很适合这种从模糊想法开始、边做边调整的功能开发。先把东西做出来,再在真实体验里不断修正,比一直停留在设计阶段更有效。
当然,AI 写代码很快,但文章和产品一样,最后还是要回到自己的表达和判断上。功能能不能用、体验顺不顺、内容是不是像自己写的,这些都得自己把关。