重生之我在 Vibe Coding 时代当程序员:第六课,第一个全栈项目

重生之我在 Vibe Coding 时代当程序员:第六课,第一个 AI 全栈项目

上节课我明白了一件事:AI 写代码越快,Git 越重要。它不是"程序员的好习惯",而是人和 AI 之间的安全栅栏。装备齐了之后,这节课拿到一个叫 user-chat 的项目,两个字:跑通。打开目录,里面有前端、有后端,有一堆我从没见过的文件。我盯着这个项目停了几秒,意识到一件事:这次不是改别人写好的代码了,而是要自己把一个"有来有去"的完整应用从零搭起来------这是第一个 AI 全栈项目。

从一个目录结构说起

user-chat 的目录长这样:

lua 复制代码
user-chat/
├── fe/
│   ├── index.html
│   ├── bootstrap.min.css
│   └── common.js
└── backend/
    ├── db.json
    └── package.json

看到 fe/backend/ 两个文件夹,前后端分离------不是课本上的概念,而是物理上的:前端代码放一个文件夹,后端代码放另一个文件夹,两边各管各的,通过网络请求连起来。

这节课要搞清楚的主线是------数据是怎么从一个 JSON 文件流进页面的

前端三件套:骨架、皮肤、神经

fe/ 里只有三类文件,分别做三件事:

  • index.html 管"页面上有什么东西"------表格、标题、导航,每一个都是一个标签
  • bootstrap.min.css 管"这些东西长什么样"------颜色、间距、斑马条纹
  • common.js 管"数据来了怎么渲染进去"------发请求、拿数据、往表格里追加行

拆成三个文件有一个很实际的理由:改一处,全局生效,不影响其他 。如果把样式直接写在 HTML 标签的 style="" 里,想改颜色就要改五十个地方;如果把逻辑混在 HTML 里,一个文件几百行,找 bug 要翻半天。拆开之后,改样式只动 CSS,改逻辑只动 JS,改结构只动 HTML------这就是模块化:每个文件只做一件事,改动的爆炸半径被限制在一个文件里。

顺带一提,common.js 开头有一行注释我觉得很重要:

js 复制代码
// 不够严格:单引号、双引号、反引号、分号、类型声明 不强求

JS 是弱类型语言,这意味着它对语法的要求比 Java 宽松得多------引号可以混用,末尾分号可以省略,变量不需要声明类型。这让 JS 的上手门槛很低,但也需要团队约定一套统一的风格。

HTML 骨架:盒子、块级行内、Bootstrap 行列

打开 index.html,整个页面在浏览器眼里是一堆套娃的"盒子"。

写 HTML 的原则是:先写盒子,再写内容 ------先决定大盒子的位置,再决定中间盒子,最后才往最里层填字。对着 index.html 数一下层次:

ini 复制代码
<main class="container">           ← 外层大盒子
  <div class="row col-md-6">       ← 中间一行
    <table class="table">          ← 表格盒子
      <thead> / <tbody>            ← 表头/表体小盒子

container / row / col-md-6 这三个 class 来自 Bootstrap:

  • container:中间内容宽度固定,左右留白,解决不同屏幕尺寸下布局不散的问题
  • row:一行,块级元素,默认占满整行宽度
  • col-md-6:一列,占父容器宽度的 6/12(一半)。Bootstrap 把一行切成 12 等份

HTML 标签本身分两大类:

类别 行为 例子
块级元素 默认占据整行,自己就是一个盒子 div header main table h1
行内元素 多个元素可以挤在同一行 span a strong img

判断方法:把两个同类元素挨着放,看它们是上下排列还是左右排列。做布局用块级,做行内高亮或链接用行内。

语义化、DOM 与挂载点

我注意到 index.html 里除了 <div>,还有 <header> <main> <aside> <footer> <thead> <tbody>。我以为这只是"写法好看",后来发现根本不是。

这叫语义化标签 ------给盒子标注身份。<main><div class="main"> 视觉上一样,但浏览器能识别 <main> 的含义,搜索引擎抓取时知道这是正文,读屏软件能直接跳到主体内容。大厂项目对语义化标签的重视程度很高------可维护性、SEO、无障碍,每一样都靠它兜底。

但让我真正重视语义化的,是它和 JS 操作的关系。

浏览器解析完 index.html 之后,会把所有标签建成一棵树状结构 ,叫 DOM 树------每一个标签变成树上的一个节点,嵌套关系变成父子关系:

css 复制代码
document
└── html
    ├── head
    └── body
        ├── header
        ├── main.container
        │   └── div.row
        │       └── table.table
        │           ├── thead → tr → th*3
        │           └── tbody → tr → td*3
        └── script

document 是这棵树的入口。document.querySelector('.table tbody') 就是"从入口出发,顺着树找第一个匹配的节点"。

common.js 里把找到的节点存进变量:

js 复制代码
const oBody = document.querySelector('.table tbody');

注意命名:o 开头表示"这个变量存的是一个 DOM 节点对象",这是一种团队命名惯例,帮你一眼看出变量类型。oBody 就是整个项目的挂载点------后面所有的动态内容都往这里"挂"。

往挂载点写内容,用的是 innerHTML +=,这一行做了三件事:读取 <tbody> 现有的 HTML 字符串 → 拼接新的 <tr> → 写回去触发浏览器重新渲染。

拼接新行用的是反引号模板字符串

js 复制代码
oBody.innerHTML += `
    <tr>
        <td>${user.id}</td>
        <td>${user.name}</td>
        <td>${user.hometown}</td>
    </tr>
`;

反引号(`````)里可以直接用 ${} 嵌入变量,比拼接字符串用 + 拼起来可读性高很多。这是 ES6 之后 JS 写字符串的推荐方式。

AI 在这节课做了什么

这节课叫"第一个 AI 全栈项目",AI 在哪里?

在设计决策上。课堂上讨论怎么搭这个页面的时候,我们用 AI 来辅助思考了两件事:

  1. 页面美观 ------ AI 聊到了 Bootstrap 这个 CSS 框架:想要一个好看的响应式表格,直接引入 Bootstrap,不用自己从零写样式规则
  2. 结构良好 ------ AI 聊到了语义化标签:想让搜索引擎正确理解页面结构,<thead> <tbody> <main> 这些标签要写对

AI 在这里扮演的角色是技术选型顾问------它不是替你写代码,而是帮你在"有哪些方案"这一步做了快速筛选。从 Prompt Engineering 到现在,这个模式没有变过:AI 负责提供选项和背景知识,你负责决定用哪个、为什么用。

json-server:30 秒拉起一个假后端

backend/ 里没有任何逻辑代码,只有 db.jsonpackage.json

package.json 是项目的"身份证",记录了依赖和可执行命令:

json 复制代码
{
  "scripts": { "dev": "json-server --watch db.json" },
  "dependencies": { "json-server": "^1.0.0-beta.15" }
}

拿到别人的项目,先跑 npm install ------ npm 读 package.json 里的 dependencies,把所有依赖下载好。node_modules/ 不需要一起发,因为这份"购物清单"在,随时能还原。

npm run dev,等价于直接跑 json-server --watch db.jsonjson-server 读取 db.json,按里面的键名自动生成 REST API:

bash 复制代码
GET /users        → 返回所有用户
GET /users/1      → 返回 id=1 的用户
POST /users       → 新增
PUT /users/1      → 修改
DELETE /users/1   → 删除

--watch 监听 db.json 文件变化,改了自动重载,不需要手动重启。

在浏览器里输入 http://localhost:3000/users,看到 JSON 数据,后端就通了。

我在这里停了一下。以前我以为"搭后端"需要学很多:Node.js、路由、数据库......但眼前一个 JSON 文件加一行命令就跑通了一个能被前端真实调用的 API。跑通一个完整链路,不需要每个环节都精通------先跑通,再补课,不要被"还没学完"挡住。

fetch + .then + 异步:为什么数据要"等一会"

前端拿数据的代码:

js 复制代码
fetch('http://localhost:3000/users')
    .then(data => data.json())
    .then(data => {
        users = data;
        const oBody = document.querySelector('.table tbody');
        for (let user of users) {
            oBody.innerHTML += `<tr>...</tr>`;
        }
    });

我第一次看到这段代码很困惑:为什么不直接 const data = fetch(...)

后来搞清楚了:fetch 是异步的 。从发出请求到后端返回数据,网络需要时间,如果 fetch 在等待时把浏览器冻住,页面不能滚动、按钮不能点。所以浏览器把 fetch 设计成"发请求,继续往下执行,等数据回来了再通知你"------叫号、坐下、等叫到名字再取餐。

fetch 立刻返回的是一张承诺票(Promise) ,不是数据。直接赋值拿到的是 Promise,不是数组。两层 .then 各有分工:

等的是什么 拿到的是什么
第一层 .then(data => data.json()) 等 HTTP 响应到达 Response 对象(快递盒)
第二层 .then(data => {...}) 等 JSON 解析完成 真正的 JS 数组(快递内容)

data => data.json() 是 ES6 的箭头函数 写法,等价于 function(data) { return data.json(); }------只有一行时可以省略 {}return

拿到数组之后,用 for...of 循环处理每一条数据:

js 复制代码
for (let user of users) { ... }

for...of 是 ES6 的语法糖,跳过了计数器------直接说"对 users 里的每一个 user,做这件事",不需要维护 i、写 users[i]、判断 i < users.length。计数循环 for(let i=0; i<n; i++) 符合 CPU 计算逻辑,性能略好,但可读性差。日常业务代码里数据量不大,可读性优先,用 for...of

这节课我学到了什么

  1. 前端三件套分离是为了"改一处,全局生效"。 HTML 管结构、CSS 管样式、JS 管行为,拆开之后每次改动的爆炸半径被锁在一个文件里,不会牵一发动全身。
  2. 语义化标签不只是好看,它是 JS 精准操作 DOM 的前提。 <tbody> 是挂载点,querySelector('.table tbody') 能找到它全靠你在 HTML 里写了这个标签。<div> 写一时爽,JS 和搜索引擎都不知道那块"div"到底是什么。
  3. json-server 让你在不写后端的情况下跑通前后端联调。 一个 db.json + npm run dev,增删改查的 HTTP 接口全齐。先跑通整条链路,再补每个环节的原理------这是 Vibe Coding 时代学东西的节奏。
  4. fetch 是异步的,数据要"等一会"才能用。 直接赋值拿到的是 Promise,不是数据。两层 .then:第一层等 HTTP 响应,第二层等 JSON 解析,只有在第二层里,数据才真正可用。
  5. AI 在全栈项目里扮演的是技术选型顾问的角色。 它帮你从"Bootstrap 还是自己写样式"、"用语义化标签还是全用 div"这些问题里快速找到方向,你负责理解背后的原因并做最终决定。
  6. 模块化 + DOM + 异步,串成了一条完整的数据流。 db.json → json-server → fetch.theninnerHTML += → DOM 树更新 → 浏览器渲染。这条线上任何一个环节出问题,你立刻知道去哪里找。

从第一课的 Prompt Engineering,到这节课第一次跑通一个真实的前后端分离项目,我越来越清楚一件事:学编程最难的不是记住语法,而是建立"数据在哪、往哪流、怎么触发"的整体感。语义化保证了 JS 能找到正确的节点,异步保证了页面在等数据时不卡死,模块化保证了改动不会失控------每一个"规范"背后都有一个具体的原因,搞懂原因,规范就不再是约束,而是武器。

下一课,继续往下挖。

相关推荐
冰西瓜60015 小时前
深度学习的数学原理(三十八)—— Transformer 完整训练代码实战
人工智能·深度学习·transformer
初心未改HD15 小时前
LLM应用开发之RAG检索增强生成详解
人工智能
用户6000718191015 小时前
【翻译】给Agent配上解释器
人工智能
明志数科15 小时前
仿真数据与真实数据:机器人训练的数据策略选择
人工智能·算法·机器学习
老司机张师傅15 小时前
AI第一章:虚拟环境库安装
人工智能
深度学习lover15 小时前
<数据集>yolo汉字识别<目标检测>
人工智能·yolo·目标检测·数据集·汉字识别
Master_oid15 小时前
机器学习43:线性回归进阶篇①
人工智能·机器学习·线性回归
香蕉鼠片15 小时前
CNN学习时的代码
人工智能·学习·cnn
AskHarries15 小时前
Google Trends 找蓝海赛道:独立开发者如何挖出没人做、但有人搜的项目
人工智能