言出法随
在这一部分,你将通过最简单的方式体验 AI 编程的魔力。无需任何编程基础,你只需要用自然语言描述想要什么,AI 就能帮你实现。这个过程就像对着魔法师说出咒语,然后眼看着你的想法变成现实。
在前面的《准备篇》中,你已经安装好了环境,包括 Claude Code(简称 cc)和 VSCode 对应的插件。
现在让我们准备一个文件夹,比如 ~/Desktop/VibeCoding (桌面上新建一个叫 VibeCoding 的文件夹),用 Vscode 打开它。大概是这个样子。

话不多说,我们先来做一个网页,它的好处是**即时可见:**你生成的页面可以立刻在浏览器中打开,看到漂亮的效果。
预期效果:
一个精美的单页面网站
实时跳动的倒计时数字
背景有渐变色和动画
直接在浏览器打开就能看到
1.1 初体验
1.1.1 随口一说
帮我做个倒计时页面
cc 马上就开始工作了,不过在执行任务的时候,cc 经常会申请所在文件夹的文件权限,或者执行命令/程序的权限,有时会弹出一个类似这样的窗口:

基本上就是3个选项:
本次可以执行
以后类似的操作,都可以默认执行
不能执行
要注意识别一些**“危险”**的命令,比如删除(rm)文件,只允许一次性执行。
当前这个命令只是创建文件,果断选 2,十几秒之后,我们就得到一个文件:

如果在 VSCode 里直接打开它,里面大概是这个样子:
代码块
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2026 新年倒计时</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
......
可以不用管内容,右键选择“在 Finder 中显示”(或者windows,“在资源管理器中显示”)

再双击打开,应该就可以在浏览器中,看到类似这样的效果了。

第一次看到这个结果的时候,难免有些小激动:原来做个页面是这么简单!真的说说话,不用懂编程,就能做应用了,这不就是传说中"言出法随"么?
没错,这就是 ai 的魅力,赋予每个人创造自己应用的“法力”!
1.1.2 提高要求
不过等等,这好像跟预期差别有点大呀...... 既不精美,也不没看出来倒计时到哪天😯。实话说,ai 还帮我们“脑补”了很多效果呢,比如圆角边框,半透明的底色,大字体等等。如果不是它这么“善解人意”,咱们这第一轮的页面,恐怕就要变成这样了:

问题在哪?这个 Prompt 太模糊了!没有说清楚:
倒计时到什么时候?
色彩和样式有什么要求
别急,我们不需要重新开始。直接在同一个对话里继续说:
现在的太朴素了,我要新年主题的:
- 倒计时到 2026 马年春节
- 深蓝色渐变背景,看起来高级
这次的结果就好多了!有明确目标时间了,背景也变成了深蓝色:

但还没有节日氛围感。
1.1.3 继续完善
加上烟花动画效果,有节日氛围

好,现在有点意思了,但还不够漂亮,尤其烟花不太像我们心目中的样子:
烟花要像真实的焰火一样升空和爆炸,要有拖尾的效果,烟花的数量多一些;
有最后一行小字"距离目标时间还有:",是没必要的;
倒计时的文字展示,也可以再美化一些

终于,一个完美的节日烟花动画出现了!
复盘:迭代的力量
为什么可以连续改进?
AI 会在原有基础上改进,不会每次都从零开始。这就像一个设计师朋友,你先说"我要个倒计时",他给你个草图,然后你一步步补充细节,它会不断完善。只要在同一个会话里,ai 会“记住”我们的聊天内容,可以一直改进。(本质上,ai 还没有记忆能力,不过这个可以以后再看)
关键经验: 每轮只加1-2个具体要求——给 AI 明确的改进方向。
现在的 ai,可以被当做一个“博学而健忘”的人来看待,它知道海量的知识,偏偏不了解你想要做的事情,想要它能“听懂”我们的话,就要学会详细地告诉它我们的应用场景和要求。
1.1.4 小结
随着使用经验的提升,我们对需求的描述会愈加熟练,就可以越来越准确和详尽地表达需求。
比如把我们的提示词写成这样,很可能就可以一次性目标:
帮我做一个【新年倒计时网页】,显示【距离 2026 年还有多少天、小时、分钟、秒】。 使用【深蓝色渐变背景,白色大字体】,加上【烟花动画效果】。 页面要【适配手机和电脑】,【数字要大而清晰】。
关键词拆解:
-
动词明确:"做一个"——告诉 AI 要创造什么
-
名词具体:"新年倒计时网页"——不是模糊的"倒计时"
-
限定条件充足:
功能:倒计时到天、时、分、秒
视觉:深蓝渐变背景、白色大字体
特效:烟花动画
适配:手机和电脑
细节:数字大而清晰
小练习:
春节很快就要过去了!把倒计时的目标,改到下一个小长假吧。
增加一个进度条,让假日的到来,越来越让人开心。
更换不同的背景色,比如表示喜庆的大红色
给页面加上背景音乐
1.2 错误处理三板斧
做练习的时候,你可能会发现,ai 也会犯错——让它实现一个背景音乐,结果连原来的烟花都显示不出来了,面对空无一物的页面,你有点欲哭无泪。别着急,我们需要跟页面打配合,告诉它发生了什么。最简单的方法,就是描述一下遇到的现象:
现在什么都显示不出来了,页面一片空白
cc 收到后,会重新阅读一遍代码,从中找出可能的问题(专业的说法,叫做代码 review)。不过这显然不是那么容易——因为我们没告诉它任何具体的错误信息。cc 盲目地从所有代码中猜测可能的问题,又慢又低效。
这时候,就要祭出我们的 vibe coding 调试三板斧了:
1.2.1 第一招:看控制台
对于我们文字描述的错误,cc 需要猜测原因,很多情况下,不如直接告诉它错误信息,更容易定位。查看这个错误信息的地方,就叫叫做控制台(console),它内置在我们的浏览器中。不同的浏览器,会有不同的打开方式。比如我们这里使用的 Chrome,就点击右上角三个点的按钮,在展开的菜单中选择:更多工具 -> 开发者工具。(或者按 F12)
查看“开发者工具”也是程序员调试的必备技能。
打开开发者工具
浏览器窗口,按 F12,或者右键点击页面,选择"检查"(Inspect),或者在菜单栏下面的位置,都可以找到它。
找到 Console 标签
打开后会看到一排标签,找到标记为 "Console" 的选项(通常在 "Elements"、"Sources" 等标签旁边),点击它。

如果程序出错了,这里通常会显示一些红色字体的信息,这些红色错误就是浏览器在报告说"我这里有 xxx问题"。
把它们复制下来,发给 cc
我的页面出错了,控制台显示: """ Uncaught NotAllowedError: play() failed because the user didn't interact with the document first. """ 这是为什么呢?
注意,在复制多行引用内容的时候,可以用一组符号,把他们跟你自己的话隔离开,就像例子中的 """(或者用反引号 ``` 也可以),这是一种让阅读更清晰的纯文字"排版"方式——把 ai 当做一个人,适合人阅读的,也适合 ai。
这段错误信息,对 ai 定位问题非常有帮助,它甚至会因此而感谢你:
你提供的信息太重要了!这个错误是因为我在页面加载时添加了自动播放音乐的代码,但现代浏览器出于用户体验考虑,不允许网页在没有用户交互的情况下自动播放带声音的媒体!
然后给出解决方案:
修改改为:页面上放一个“播放音乐”按钮,或者让用户点击任意区域后再播放,可以么?
在征得你的同意之后,ai 会自动修复它。
1.2.2 第二招:贴图
并不是所有的错误,都能在控制台找到错误信息的,很多时候,只是因为我们的指令不太清晰,被 ai 误解,做出来的效果不符合预期。
比如我在做这个练习的时候:
把倒计时目标,改到端午节
Cc 快速完成了修改,甚至还添加了非常漂亮的鲤鱼图标,但是左上角却出现一个莫名其妙的问号:

这时如果只能口头描述页面的实际情况,和需求的差异,是不太容易说清楚的,好在现在的 ai 模型,大部分都自带了“眼睛”,可以看到我们提供的图像。
我们就可以截图 + 标注错误点之后,粘贴给 cc:

Cc 回答:
问题已经解决了!问号是因为之前的emoji编码有问题。我已经修复了:
标题:改为"2026 端午节倒计时"
页面标题:使用🥟(粽子)emoji替换了有问题的🎏 emoji
目标日期:设置为2026年6月17日(端午节)
现在倒计时页面应该正常显示,从2026年2月1日到6月17日还有136天的倒计时,没有问号问题了。页面会显示天、小时、分钟和秒的实时倒计时,还有漂亮的烟花动画效果。
1.2.3 第三招:持续迭代
刚才的修改明显还有问题,我们从对话中也能看出来图标不太对,那么还可以继续让它修改:
你这是粽子么?这是饺子啊
对不起,我理解错了,但是没有粽子的 emoji 图标,我用改竹子🎋代表了,这样既有端午节的特色,又能准确表达。

类似的问题,可能会经常出现,我们需要一些耐心,一次次反馈错误信息,持续调教,直到满足需求为止。你会发现,虽然目前的 ai 已经很强了,cc 又是最好用的 vibe coding 工具,它还是经常犯低级的错误。这是因为在本质上,ai 还没有长期记忆的能力,所有的信息,其实都保存在一次会话的聊天记录当中,聊得长了,就难免捡起这个,忘了那个,甚至前后内容夹杂不清。
好在我们这个初体验项目比较简单,怎么样才能更好地管理聊天记录,会在后面的实战项目中讲到。
1.3 本地文件整理
刚才的第一个项目,在网页版的 ChatGPT (豆包,Deepseek)工具中也能生成。现在这个难度不高,却只有 cc 这样的本地 agent 可以胜任。
1.3.1 杂乱的文件
你可能经常遇到这种情况,桌面或者某个文件夹里,堆满了杂乱不一的文件,可能是一堆 excel,word 或者其他文档。从名称完全看不来含义,很影响摸鱼工作效率,这时候,你非常想要整理它,但一想到一个个点开看内容,再自己起名字,就泄气了。
现在有了 cc 这个全能助手,终于可以着手开始了:
比如你有下面这样一堆文件:

它其实是一整部小说,内容大概是:

但只看文件名会觉得 WTF ?!,排列的顺序也是杂乱的,根本没法顺畅阅读。下面我们就用 cc 来整理一下:
用 VSCode 打开对应的文件夹,在 cc 聊天窗口输入:
(这里建议你先别看书中给出的提示词,带着“倒计时”项目的经验,自己尝试一下,该怎么说清楚这个需求)
1.3.2 完美的整理
当前文件夹下面,有一些文本文件,他们是一本小说的各个章节,请根据内容,帮我整理它们的文件名,让它们看起来有意义,而且按顺序排列。
可以看到 cc 会认认真真地阅读每一篇文件的内容:

中间会有两三次需要我们确认的命令(给文件改名),全部确认之后,结果是这个样子的:

非常完美吧?你会发现并不需要告诉 cc,它应该怎么做,只要说明你需要什么就好了。
比如我们并没有让它读取每个文件的内容,用一句简短的表达提取大意,并且中英文混合,也没告诉它用 01,02 这种方式编号(如果是 1,2,3...... 11,12的话,可能排序就不对了),是它自己根据上下文推断出来的。
这里要注意:
整理文件的任务:最好控制一下文件夹的范围,不要在一个大的顶级文件夹下面操作(比如桌面),以避免误操作影响太大。
让我们确认操作命令的时候,还是要小心谨慎,一定理解了再确认,如果没有理解,就选择 “No”,让 cc 解释一下要执行的命令,再继续。
- 实战项目:喵宇宙
在上一节里,你体验了用一句话生成小项目的乐趣,也顺便学习了一点错误反馈的技巧。但这些项目都是“一次性”的——生成后就完成了。现在,我们要做一个**真正的项目:**从最简单的版本开始,一步步添加功能,最终部署上线,成为一个可以分享给朋友的应用。
2.1 做什么
喵宇宙是一个在线猫咪展示平台。你可以为猫咪创建专属卡片,上传照片,创建个性化展示空间。做好的展示卡片可以轻松分享到微信、微博和朋友圈,在电脑和手机上随时查看。
2.1.1 为什么选这个项目
有趣
猫咪是人类最好的朋友之一,人人都爱晒猫,哪怕你自己没有养,也可以获得很多朋友的喜爱。你还可以和朋友比谁在社区中发现其他人的猫咪,收获满满的快乐。
友好
这个项目的学习曲线非常友好,只需5分钟你就能创建第一个猫咪卡片,10分钟上传自己的猫咪照片,30分钟做出精美的展示页面,1小时后就能拥有完整的展示馆。后续还可以添加特效让猫咪更萌,可以将项目部署上线,让全世界都能访问。
实用
这个项目做完之后,真的可以用起来,展示自己家的喵星人,把它可以分享给朋友(建立猫友社区),还可以举一反三创作更多的作品(狗狗展示馆、宝宝成长册、旅行相册等)。
2.1.2 演进路线
在“入门章”我们将分 5 个阶段,来完成这个项目,如果你有兴趣,后面的“进阶章”还会继续更多的挑战。
flowchart TD
stage1["阶段 1: 静态猫咪卡片<br/>⏱️ 5分钟<br/>📋 HTML/CSS布局"]
stage2["阶段 2: 照片上传和展示<br/>⏱️ 10分钟<br/>📋 File API"]
stage3["阶段 3: 多图轮播<br/>⏱️ 40分钟<br/>📋 轮播组件"]
stage4["阶段 4: 信息编辑<br/>⏱️ 1小时<br/>📋 表单处理"]
stage5["阶段 5: 导出和分享<br/>⏱️ 2小时<br/>📋 综合调试"]
stage1 --> stage2
stage2 --> stage3
stage3 --> stage4
stage4 --> stage5
classDef frontend fill:#90EE90,stroke:#2E8B57,stroke-width:2px,color:#000
classDef data fill:#87CEEB,stroke:#4682B4,stroke-width:2px,color:#000
classDef fullstack fill:#FFB6C1,stroke:#DC143C,stroke-width:2px,color:#000
classDef milestone fill:#FFD700,stroke:#FF8C00,stroke-width:3px,color:#000
classDef note fill:#FFF8DC,stroke:#DAA520,stroke-width:2px,color:#000,stroke-dasharray: 5 5
class stage1 frontend
class stage2 fullstack
class stage4 note
2.1. 需求定义
跟之前的一句话项目不同,咱们这个喵宇宙稍稍繁杂一些,还准备上线以后可以长期提供服务。所以在正式开始编码之前,你需要做一些准备工作。就像盖房子要先画图纸、准备工具一样,做项目也需要先定义需求、准备环境。
2.1.1 什么是 PRD(产品需求文档)?
PRD 是 Product Requirements Document 的缩写,用来描述"我们要做什么"。
你可能会想:“我不是在和 AI 对话吗?为什么还要写文档?”
当项目变得复杂后,一句话说不清楚所有需求,文档能帮你理清思路,避免遗漏重要功能。更重要的是,文档是给 AI 看的“产品说明书”,无论开多少个会话,AI 都能看着文档生成符合你需要的代码。
好消息:PRD 不需要很复杂,用自然语言写清楚就行!
2.1.2 MVP 版本的 PRD
MVP 是 Minimum Viable Product(最小可行产品)的缩写,指的是最简单但能用的版本。
采用 MVP 的方式开发有很多好处:它能让你快速看到成果,获得成就感和反馈;避免一开始就陷入复杂功能的泥潭;更重要的是,你可以先验证核心想法是否可行,再决定是否投入更多时间。就像搭积木,我们先搭好基础框架,确保它稳固,然后再一层层添加更多精彩的部分。
对于喵宇宙项目,我们先从最简单的版本开始:一个展示猫咪信息的卡片。
PRD 文档示例(阶段 1 MVP 版本):
代码块
### 项目名称
* 喵宇宙 —— 猫咪卡片展示
### 功能描述
* 一个展示猫咪的信息和照片的网页。
### 核心功能
* 显示多张精美的猫咪卡片
* 卡片包含:猫咪名字、年龄、性格描述
* 卡片设计精美,有阴影和圆角效果
### 技术要求
* 所有代码放在一个 HTML 文件中,名字叫做 index.html
* 纯前端实现,无需后端
### UI 风格
* 温馨可爱的风格
* 主色调:温暖的橙色或粉色系,配紫色背景
* 卡片式设计,有阴影和悬浮效果
* 手机和电脑都能正常显示
这就是一份简单但完整的 PRD! 你可以把它保存为 prd.md 文件,放在项目文件夹里。
小贴士:你可能对前后端的概念还不太理解,简单来说,"前端"是指代码完全在浏览器中运行,用户看到的界面和交互都由浏览器实现,而"后端"则运行在服务器上,负责处理数据等用户看不到的部分——我们会在进阶章引入后端。如果想深入了解,可以看 AWS 的。
让我们来理解一下这份文档:
**项目名称:**给你的项目取个响亮的名字,让所有人一眼就知道这是什么。我们叫"喵宇宙",既点明了主题是猫咪,又带有一点想象空间。
**功能描述:**用一句话概括这个项目是做什么的。别小看这一句话,它能帮你理清核心目标。如果你发现一句话说不清楚,那可能需求还不够聚焦。
**核心功能:**列出具体要做什么。注意这里我们只列了三条:显示卡片、卡片内容和设计效果。没有写"用户登录"、"收藏功能"、"分享朋友圈"——那些都是后续版本可以考虑的,MVP 阶段我们要克制。
**技术要求:**告诉 AI 怎么实现。这里特别强调"所有代码放在一个 HTML 文件中",是为了咱们学习的时候看起来方便。
**UI 风格:**描述视觉感受。用"温馨可爱"、"温暖橙色"这类感性的词,而不是"#FF6B6B"这种精确的颜色表达。因为在这个阶段,我们关注的是感觉对不对?具体颜色可以让 AI 去搭配。
可以看到,PRD 里没有用什么专业术语,就是顺着思路写下来:做什么、怎么做、做成什么样。你完全可以按照这个套路,把自己的想法变成文档。
2.2 启动
2.2.1 阶段 1:生成 MVP — 第一个猫咪卡片
现在,一切准备就绪!让我们生成第一个版本:
参考文档 prd.md 描述的内容,做一个猫咪展示卡片。
发送这个提示词后,cc 会:
读取你的需求文档
生成一个 index.html 文件
文件包含完整的 HTML、CSS、JavaScript 代码
自动保存到你的项目文件夹
现在运行你的第一个项目:
在项目文件夹中找到 index.html
双击打开(会在浏览器中打开)
看到一个精美的猫咪卡片
成就感时刻:当你看到第一个猫咪卡片出现在浏览器中,恭喜你——你完成了喵宇宙的第一步!生成的界面是类似这样:

虽然名字有点“货不对版”,比如叫雪球的看起来是只三花😂,但也算是像模像样了。
代码阅读
这里我们第一次看一下代码内容:
代码块
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>喵宇宙</title>
<style>
/* CSS 样式代码 */
/* 包含:卡片布局、颜色、阴影、圆角等 */
</style>
</head>
<body>
<div class="container">
<h1 class="title">🐱 喵宇宙 </h1>
<div id="cardsContainer" class="cards-grid">
<div class="loading">
<div class="loading-spinner"></div>
<p>加载中...</p>
</div>
</div>
</div>
<script>
// Sample cat data - 示例猫咪数据
const catsData = [
{
id: 1,
name: "小橘",
breed: "橘猫",
age: "2岁",
gender: "公",
description: "性格温顺,喜欢晒太阳,对小鱼干没有抵抗力。是个不折不扣的吃货,看见食物就会喵喵叫。",
image: "https://images.unsplash.com/photo-1574158622682-e40e69881006?w=500&h=400&fit=crop",
badge: "最受欢迎",
tags: ["温顺", "亲人", "吃货"]
}, ......
</script>
</body>
</html>
第一次看代码,你会觉得一脸懵,不要慌,让我们用简单的方式理解一下HTML 的结构。你可以把HTML想象成一本书:
-
<head>就像书的封面和版权页——包含书名(网页标题)、出版信息等,这些内容读者翻开书时看不到,但对书很重要。比如<title>喵宇宙</title>决定了浏览器标签页上显示什么名字。 -
<body>就是书的正文内容——读者真正看到的文字、图片、按钮等都在这里。比如<h2>小橘</h2>会在页面上显示"小橘"这个标题。
所有的区域,都是采用 <xxx> </xxx> 的样式包裹起来,这是 HTML 语言的规范。
你会发现代码里有很多中文,从这些中文就能看出内容的对应关系。最棒的是那些双引号 " " 里面的文字,你可以直接修改,改完保存,刷新浏览器,页面就会跟着变化。这就像编辑Word文档一样简单,只不过现在编辑的是网页。
现在不需要理解每一个标签的含义,先大胆地改改看,感受一下代码和页面的对应关系。想深入了解 HTML 的同学,可以关注老师关于 。(阮一峰老师编写了大量深入浅出的教程,他的博客,是入门学习编程的好地方。)
小练习:
试着改变卡片颜色:对 cc 说"把卡片背景改成浅灰色"
给猫咪起更合适的名字
试着添加更多信息:对 cc 说"添加一个'爱好'标签",并尝试理解新加的 HTML 内容
适应手机
如果把这个index.html文件发送到手机(比如通过微信),我们会发现它还挺适合在手机中观看——这是 ai 足够聪明,预判了我们的需要,以往为了调整这个效果,前端程序员还需要花费一番功夫呢。

到目前为止,我们的 ai 都足够聪明,甚至都没用上第一节中提到“错误处理三板斧”,这是得益于cc强大的上下文处理能力。不过错误随时可能会出现,如果你自己验证的时候,遇到了什么问题,别忘了把三板斧拎出来试试。
2.2.2 阶段 2:照片上传和展示
现在你已经有了一个精美的猫咪卡片。但是你会想:"这些都是网图啊,我想放上自己家主子的照片!"。没错,这正是我们接下来要做的——让卡片能够展示真实的猫咪照片。
我们需要添加一个"选择照片"按钮,当你点击它时,会弹出文件选择窗口让你挑选照片。选好后,照片会自动显示在卡片上,而且还会自动调整大小,刚好适配卡片的显示区域,不会变形或拉伸。
现在,让我们来告诉 AI 我们想要什么。你可以这样对 cc 说:
代码块
在现有功能基础上,添加照片上传功能:
1. 在卡片上方添加一个"选择照片"按钮
2. 点击后打开文件选择对话框(只允许选择图片文件)
3. 用户选择图片后,自动替换卡片上的占位图
4. 图片自动缩放和裁剪,适配 300x200 的显示区域
5. 保持图片比例,不要拉伸变形
保持代码注释清晰。
发送这段话之后,Claude Code 就会开始工作了。它会修改你的 index.html 文件,添加文件选择按钮和相关的 JavaScript 代码。这些代码会处理文件读取和图片显示——听起来很复杂,不过 AI 会帮你搞定所有细节。
好了,代码生成完毕!让我们来测试一下效果。首先刷新浏览器页面,你会看到出现了一个"选择照片"按钮(你的界面肯定会有点不同,但大致排列是一样的)。点击它,会弹出文件选择窗口。从你的电脑里挑一张最可爱的猫咪照片,然后点击确定——你的猫咪照片出现在了卡片上!

替换完是这样子的:

而且下次再打开这个网页的时候,替换的照片也会被保留哦。
但是上传的照片效果,不太完美——你会发现它被裁掉了一截,没能完全展示出来。所以你可以继续提要求:
上传的照片需要完全展示,不能截取部分
Cc 这次的反应会很快,几秒钟的时间就完成修改,信心满满地告诉你“好了,去看吧”。但是当你真的开始上传照片的时候,啊额,报错了~:

这个报错未必现在才出现,如果你刚才玩得多一点,上传了好几张照片,很可能就已经提前报了。这到底是什么原因呢?
还记得 #1.2 节的“错误处理三板斧”么?把这个报错先截个图,再按 F12 打开“开发者工具”,去控制台里面看看报错,果然有一行红字:

现在把它们都扔给 cc,让它给我们解释一下:
再次上传图片报错了:
index.html:676 无法保存图片到本地存储: QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of 'cat-images-1' exceeded the quota.
at index.html:673:38
Cc 思考一会儿就告诉了我们答案:
这是 localStorage 存储空间不足的问题。Base64 编码的图片占用空间很大,多张高清图片很容易超出浏览器的存储限制(通常为 5-10MB)。
现在让我改进错误处理,当存储空间不足时自动清理旧数据或限制图片数量:
Edit index.html
Added 14 lines
已完成修改。主要改进:
添加图片压缩功能 - 上传前自动将图片压缩到最大 1200x900 像素,JPEG 质量 80%,可大幅减少存储空间占用
改进错误处理 - 当存储空间不足时,自动限制最多保存 3 张图片,并给出更友好的提示
压缩后的图片通常会从几 MB 降到几十 KB,应该能解决存储空间不足的问题。
还自动带了压缩功能,看起来很强大的样子,不过这只对新的图片生效,当你尝试再次上传图片的时候,还是可能会超限,并收获“只能保存3张”的提示。你对此表示不满,并且寻求更好的解决办法:
但现在已经存了那么多?空间不够了,我怎么才能清理一下?
Cc 终于领会了你的意图,直接给了你 3个方法:
在浏览器控制台(F12)执行以下代码来清理存储:
方法1: 只清理猫咪图片(推荐)
方法2: 查看占用空间详情
方法3: 清理所有猫咪数据(包括编辑的信息)
执行后刷新页面即可重新上传图片,新的压缩功能会自动生效。
原来控制台还可以执行代码!你马上来试一下:复制方法1的一小段代码到控制台:

按下回车键执行:

现在已经清理掉所有之前上传的大图片,又可以轻松上传了呢,而且新上传的图片都被压缩过了,会很节省空间。
小贴士:浏览器只能提供 5MB 的空间保存文件,这非常狭小,但是别着急,现在先体验创造的乐趣,到了进阶章,咱们再彻底解决它。
对啦,别忘了我们的初心,本来是要显示完整的“小橘”照片来着,现在它已经完整展示了:

这是下一个成就时刻:用自己的猫咪照片制作了第一个展示卡片!赶紧截图发给朋友炫耀一下吧,当他们问"这是用什么工具做的",你可以骄傲地说"我自己写的"。
小贴士:如果你选择图片后没有显示,可能是浏览器的安全策略在作怪,试试刷新页面,或者把错误信息复制给 AI,让它帮你排查问题。如果图片显示得很模糊或者变形了,告诉 cc "图片显示有问题,请保持原图比例",它会帮你调整。
2.2.3 原理解释
你可能好奇背后的原理。简单来说,浏览器提供了一种叫 File API 的能力,让网页可以读取你电脑上的文件。当你选择一张照片后,浏览器会创建一个临时的图片链接,然后代码把这个链接设置给卡片上的图片元素。下面是 AI 可能生成的代码片段,看看就好,现在不用完全理解(后面我们会删除这个调用 /手动狗头)
代码块
// 文件选择按钮的事件监听
function processAndDisplayImage(file, imgElement, catId) {
const reader = new FileReader();
// Read file and convert to data URL - 读取文件并转换为数据URL
reader.onload = (e) => {
const imageUrl = e.target.result;
// Update image source - 更新图片源
// CSS object-fit: cover will handle cropping automatically
// CSS的object-fit: cover会自动处理裁剪
imgElement.src = imageUrl;
// Store in localStorage for persistence - 存储到本地存储以持久化
try {
localStorage.setItem(`cat-image-${catId}`, imageUrl);
} catch (e) {
console.warn('无法保存图片到本地存储:', e);
}
};
reader.onerror = () => {
alert('文件读取失败,请重试');
};
// Read file as data URL - 读取文件为数据URL
reader.readAsDataURL(file);
}
/**
* Load saved images from localStorage
* 从本地存储加载保存的图片
*/
function loadSavedImages() {
catsData.forEach(cat => {
const savedImage = localStorage.getItem(`cat-image-${cat.id}`);
if (savedImage) {
const imgElement = document.querySelector(`.cat-image[data-cat-id="${cat.id}"]`);
if (imgElement) {
imgElement.src = savedImage;
}
}
});
}
到这里,你已经完成了两个阶段的开发!你的猫咪展示卡片不仅有精美的设计,还能上传的真实猫猫照片了。你学会了如何用自然语言描述功能需求,如何在现有基础上一步步添加新功能。虽然你对上面提到的 File API 这个概念,可能还有点模糊,但你也发现了:就算不懂技术细节,也能做出很棒的东西。
对了,既然已经添加了上传自家猫猫照片的功能,我们的 PRD 也应该相应地更新啦,在本轮会话的最后,对 cc 说:
功能已经完成了,帮我更新 PRD 文档吧。
你会发现 PRD 的核心功能处,被添加了几行文字:

记得以后每次添加了新功能,都要让 cc 帮我们更新文档,这样等项目做完,我们的 PRD 也就随之完善好了。
2.3 增强
2.3.1 阶段 3:多图轮播
不用我说,你可能已经对咱们的“喵宇宙”感觉到不足了:一张照片怎么够展示你家主子的盛世美颜呢?卖萌的、睡觉的、玩逗猫棒的......每一张都值得展示!所以这个阶段,我们要让卡片支持多张照片轮播,就像翻电子相册一样。而且,我们还要添加编辑功能,让你可以随时修改猫咪的名字、年龄、性格等信息。
想象一下效果:你一次性选择了五张照片,它们会自动轮播,每3秒切换一张。你还可以用左右按钮手动切换,就像在手机上翻相册一样。卡片上会显示"1/5"这样的指示器,告诉你现在是第几张。当你觉得猫咪的介绍需要更新时,点击"编辑信息"按钮,名字和性格描述就会变成可编辑的输入框,改完点"保存"就更新了,点"取消"就恢复原样。
是不是已经迫不及待,要开始指挥 cc 工作了?不过别忘了在认知篇中提到过的原则:复杂任务需要拆解——刚才我们想要的有点多,不要一次性告诉 ai,而是拆成多个需求,一步一步来。
先做多图轮播,记得新建一个会话再开始,新建按钮就是右上角的 +;

之前我们在言出法随里,每个项目都只有一个会话,那是因为这些项目比较简单,对于像喵宇宙这样复杂的项目,咱们要记住一个原则:每个功能一个独立会话。
为什么这么麻烦?那是因为目中 ai 采用的大语言模型技术,没有记忆能力,cc 每次回复,其实都是查看了会话中所有的聊天记录,才知道上下文的。结果就是聊天记录越来越长,不但非常浪费钱(大语言模型按照对话的字数收费),而且会导致 ai 越来越“笨”,经常会把很久以前聊到的需求和问题,也夹带到当前的功能中来。所以我们要按照功能,来拆分不同的会话。如果发现之前哪个功能改得不够满意,想微调一下,还可以回到原来的会话继续。
点击 Cc 界面左上角的 Past Conersations ,就可以列出所有会话。

聪明的你,马上会想到:我有一些要求,是不属于功能的,比如字体、颜色这些,总不能每次新开一个会话都输入一遍吧?没错,这正是我们需要组织一个 PRD 文件的缘故:那些统一的要求,已经实现的整体功能,都放在 PRD 里就好了,需要的时候,可以在文字里,让它参考 PRD。
现在我们在一个新会话中输入:
在现有功能基础上,添加多图轮播:
- 文件上传的时候,支持一次选择多张图片
- 添加一个轮播图组件:
- 自动播放,每3秒切换一张
- 有左右切换按钮
- 显示当前是第几张(例如:1/5)
注意为了让表达清晰,我们这次的文字不但分了多行,还用到了 1、2、-,以及缩进这些方法来让条理更清晰——ai 很“愿意”阅读这些分条列项的表达,因为可以更清晰地理解我们的意图。
经过几次工具使用的确认之后,cc 完成了我们的修改。点击"选择照片"按钮,这次你可以按住 Ctrl(Windows)或 Command(Mac)键,一次选中多张照片。

选好后,第一张照片会立即显示出来,然后每隔3秒自动切换到下一张。你还可以用左右按钮手动翻页,卡片上会显示"3/5"这样的数字,告诉你现在看的是第几张。

记得告诉 cc,帮我更新 PRD ,以后教程里就不赘述了。
2.3.2 阶段 4:信息编辑
下面要解决“货不对版”的问题了:比如我们上传的小橘明明是只小奶猫,却号称2岁了,更别提叫“虎斑”的是只奶牛,却把真正的虎斑叫布偶了。
添加信息编辑功能:
- 添加"编辑信息"按钮,点击后:
- 猫咪名字、年龄、性格变成可编辑的输入框
- 显示"保存"和"取消"按钮
- 点击"保存"后,更新显示的信息
- 点击"取消"后,恢复原来的信息
UI 要美观,编辑状态和显示状态要有明显区分。
这段提示词里,我们把编辑的过程都描述了出来,包括编辑状态和平时显示状态的区分,这其实就是一种“产品经理”的思维了,很多年前,移动互联网刚刚流行的时候,有一本书叫《人人都是产品经理》,作者恐怕没想到,它会以这种方式来实现。
我自己在做这个需求的时候,cc 到这里没能一次性完成,它修改后的页面,无法再上传图片了(点击按钮没有反应)。于是开启我的“报错-反馈-修改”迭代:
我测试了一下,修改属性是成功的,也保存了,但是这回上传图片失败了,点击“选择照片”按钮没有反应。
经过这次"指导",它很快意识到自己的错误,并且修复了代码。现在刷新浏览器,让我们来体验一下新功能。

小贴士:ai 总会犯错,这很正常,把出错的信息尽量清晰地告诉它,让它来排查错误原因就好,一般经过2-3轮排查和修改,它都能修复错误,继续工作。
点击"编辑信息"按钮,你会发现猫咪的名字、年龄、性格都变成了可以输入的框。随便改点什么,比如把"活泼好动"改成"高冷傲娇",然后点"保存"。

嘭!卡片立刻更新了。如果你改到一半反悔了,点"取消"就能恢复原样。
这是你的又一个里程碑:一个功能完整的猫咪展示页面!
小练习:试试对 cc 说
"添加暂停/播放按钮,控制自动轮播",
"添加删除照片功能,可以删除不想要的照片"
"我觉得原来自动裁切的效果更好,帮我加个按钮切换不同显示方式"。
每一个新功能都会让你的网页更丰富。
最后,别忘了更新 PRD 呦。
2.3.3 阶段 5:分享动图
现在展示页面的功能已经很完整了,但你可能会想:我上传的这些照片,还有酷炫的轮播效果,朋友也看不到啊?有一个最简单的方式,就是把它们保存为动图。我们会添加一个实用的"保存gif"按钮(gif 是一种可以变化的图片格式,很多动态的微信表情包,就是基于它生成的),点击它时,卡片会被导出为动图,自动下载到你的设备,然后你就可以把图片发到任何地方了。
来告诉 cc 我们的需求:
添加一个按钮,
-
将卡片轮播内容导出为 gif 动图
-
自动下载,文件名为"猫咪-[名字].gif"
-
按钮尽量不要显眼(以免破坏美观)
如果不出意外的话,这轮生成应该会报错了 🐶。别看它是个小功能,实现起来还蛮复杂的,我的 cc 为此要工作了7、8分钟。完成后第一次打开,确实看到导出的小图标按钮:

然而点击它却没有什么反应。
现在的你已经身经百战,不会慌了,祭出“三板斧”之一的“查看控制台”,看看有没有什么报错,果然发现一条红色的文字:

把它复制下来发给 cc:
导出失败了,控制台显示:
Uncaught TypeError: Cannot read properties of null (reading 'triggerDownload')
at index.html:1164:42
at gifshot.min.js:8:5991
at gifshot.min.js:8:18994
at a (gifshot.min.js:8:9855)
Cc 思考后发现,是triggerDownload 这个变量还没赋值就被引用了,它很快修复了这个 bug。但这一次非常奇怪:点击导出按钮后,它变成了沙漏的状态,好像正在进行中,但一直都没有结束。我们来截图告诉 cc:

这回它思考了一会儿,觉得问题应该出在跨域访问上:

并且推测应该是默认的图片才会报错,自己上传的反而不会,我们尝试了一下,果然如此!点击“雪球”的导出,就能下载 gif 图,于是把这个信息也反馈给 cc:
确实是这样,只有默认的图片导出会变成沙漏。
Cc 确认了问题跟推测一致,一会儿就修复好了,现在所有的猫猫都支持导出!
可是等一下,怎么有时候导出的动图是正常的,有时候是黑色的呢?

继续反馈问题:
怎么有时候导出的图片是全黑的呢?你管这个叫雪球?控制台也没有报错。
Cc 经过一段长时间的思考,得出了如下结论:点击太快了,页面还没来得及加载所有图片,我们就开始导出。

并且给我们加了一段调试代码用于验证:
console.log('图片尺寸:', img.width, 'x', img.height);
// 输出: 图片尺寸: 0 x 0 ← 证明还没加载完!
现在我们尝试刚刚刷新页面就点导出,果然在控制台看到了这样的输出:

问题确认,解决起来就快了,回复之后,cc 很快给出处理方法,还顺便告诉我们关键知识点。
完成这个功能后,你就可以点击"保存为图片"按钮,卡片会被导出为一张精美的动图并自动下载到你的电脑。

成就感时刻:现在可以不但能在网页中欣赏自家猫猫的美图,还可以导出动图分享给朋友啦!这就去发一张朋友圈吧。
这一阶段的难度明显增加,cc 也需要我们更多的反馈和修正了,这正是 vibe coding 的常态,是我们和 ai 共同“创造”产品的过程。
总结
恭喜你!跟随本章一路走来,已经完成了一个令人惊叹的转变:从零编程经验,到独立创建自己的 Web 页面。
回顾这段旅程。你从一个简单的新年倒计时页面开始,通过几轮对话就让烟花在深蓝色的渐变背景上绽放,数字精准地跳动着倒计时。然后你完成了更复杂的喵宇宙项目,从最初只显示几张猫咪卡片,到支持上传自己的照片,再到实现多图轮播、信息编辑,最后还能导出精美的动图分享给朋友。这两个项目看起来简单,但背后涉及的技术细节其实相当丰富——只不过 AI 帮你处理了那些复杂的部分。
更重要的是,你掌握了 Vibe Coding 的核心方法。你学会了用“言出法随”的方式,用自然语言向 AI 描述需求,让它为你编写代码。你体会到了迭代的力量,不再追求一次就做到完美,而是通过多轮对话逐步完善作品。当遇到问题时,你知道该打开浏览器控制台查看错误信息,知道可以截图标注问题点,也懂得了要给 AI 足够的耐心和反馈,让它一步步调整到符合你的期望。
在这个过程中,你还学会了如何清晰地表达需求。动词要明确(“做一个”而不是“想要”),名词要具体(“新年倒计时网页”而不是“倒计时”),限定条件要充足(要说明功能、视觉、特效、适配等各方面的要求)。你也掌握了在同一会话中持续改进的技巧,理解了 AI 的局限性——它很博学却容易"健忘",需要我们不断地提供上下文和反馈。
Vibe Coding 的本质
通过这一章的实践,你应该已经感受到:**Vibe Coding 并不是让 AI 完全替你编程,而是人机协作的创造过程。**你提供创意、需求和反馈,AI 负责实现细节和处理技术问题,然后你们一起迭代打磨,最终创造出独一无二的应用。
这个过程中,你不需要记住各种编程语法,不需要背诵复杂的 API 文档,但你需要知道自己想要什么。清晰的目标是一切的起点。你还需要能用自然语言准确地描述需求,这种沟通能力比编程技能更重要。同时你要有敏锐的判断力,能发现哪里不对劲,能给出具体的反馈。最后,你需要足够的耐心,愿意一步步迭代完善,而不是指望一次就完美。
当前的限制
不过坦白说,现在你手中的作品还有一些明显的局限。它只能在你自己的电脑上运行,朋友想看的话,你得把整个 HTML 文件发给他们。所有数据都保存在浏览器的本地存储里,不仅容量极其有限(只有 5MB),而且一旦清理浏览器缓存就会全部丢失。你的应用也没有用户系统,每个人看到的都是同样的内容,无法实现个性化。更重要的是,这些应用缺少真正的"后台",所有逻辑都在前端,无法处理复杂的业务场景。
这些限制,正是我们在进阶章即将突破的目标。
预告:打造真正的 Web 应用
如果说入门章让你体验了创造的乐趣,那么进阶章将教你构建真实、完整、能够服务全世界用户的 Web 应用。
让我们一起向进阶篇进发!