全栈小项目手记:前后端分离 + 模块化 + json-server 实践
最近跟着笔记做全栈练习,从零搭了一个用户列表页面。前端用三件套,后端用 json-server 模拟。把整个过程里涉及的设计思想、布局习惯、标签语义、DOM 操作都过了一遍,顺手记下来了。
1. 前后端模块化分离
项目一开始就定了前后端分离的目录结构:
fe目录:前端代码放这里,前端专注页面和交互backend目录:后端代码放这里,后端专注提供数据和接口
这样后面改前端样式不会碰后端逻辑,后端换接口也不会影响页面结构。
2. 前端三件套,各干各的
前端就是老三板斧:HTML、CSS、JS。
- HTML 负责结构,写标签
- CSS 负责样式,一般在头部引入
- JS 负责交互,用 script 标签引入,比如
common.js
早点把 HTML 和 CSS 定下来,页面就能更早让用户看到。页面看到后,再添加js 行为 script 如果将其放在head则会阻塞html和css结合,应该将script 放到body 的结束之前。
3. 模块化设计思想:一个文件只做一件事
刚开始写代码喜欢把所有功能和代码都塞一个文件里,后面发现三个问题:
- 不好维护
- 不好扩展
- 不好优化
所以模块化的思路是:每个文件夹有职责划分,每个文件只做一件事(甚至一个类只做一件事)。比如前端里,JS 只负责数据处理和渲染,CSS 只负责样式,HTML 只负责结构。
4. HTML 结构:先写盒子,再写内容
写页面时我习惯先把盒子搭出来,再往里面填内容。
- 盒子概念很重要
- 一个盒子套一个盒子,先把布局框架写清楚
5. CSS 布局:container + row + col
CSS 业务上用了一套经典布局:
container:中间内容宽度固定,左右留白。这是 PC 时代不同尺寸设备的通用布局方式row:表示一行col:表示列
行列布局用起来很清晰,一行一行地排内容。比如我项目中这行代码:
<div class="row col-md-6 col-md-offset-3">
意思是一行,占一半宽,再往右推 3 列以达到居中的效果。
6. 用 Bootstrap 框架快速出样式
如果为了让页面好看一点,又不想手写太多 CSS,可以直接用 Bootstrap 这样的 CSS 框架。
7. 语义化标签:别老用 div
HTML 标签默认分两类:
- 块级元素:用来做盒子
- 行内元素:用来装内容,兄弟元素可以并排显示
不要 div 满天飞。div 是块级容器,但不能一直只用它。像 header、footer、aside、main 这些语义化标签,比 div 更有意义。搜索引擎和屏幕阅读器能更好地理解页面结构。
写表格的时候,thead 和 tbody 非常重要。例如:
html
<table>
<thead>
<tr><td>...</td></tr>
</thead>
<tbody>
<tr><td>...</td></tr>
</tbody>
</table>
thead 加 tbody 能让表格语义更清晰。
8. HTML 文档的本质和 DOCTYPE
HTML 文档都是文本类型。有两种常见文本类型:
text/plain:纯文本text/html:HTML 标签文本,浏览器用 HTTP 超文本传输协议拿到后,会解析成 document
文档开头要写 <!DOCTYPE html>,这个 ! 表示这是 HTML 最新版本(HTML5),跟 HTML4 有区别。
9. DOM 编程:从页面到 JS 内存
DOM 编程就是 JS 操作文档对象。浏览器把 HTML 解析成一个 document 对象,我们可以用:
document.querySelector()配合选择器去查找元素.innerHTML动态修改 DOM 的内容
这样就把 HTML 页面带到了 JS 内存里来操作。
10. 大厂特别注重的底层能力
大厂面试很喜欢考底层:
- HTML 语义化标签
- JS DOM 编程
- 模块化、动态插入 HTML
JS 在浏览器里准备好了 document 对象,它是树状结构。document.documentElement 是根节点,document.body 是页面主体。用 document.querySelector 可以去遍历这棵树,查看节点、孩子节点、兄弟节点,把新节点挂载上去。
11. 后端准备:用 json-server 快速起服务
JS 确实通天,前端、后端、AI 都能写。后端这边我们用一个轻量方案:
npm init -y生成package.json,这是后端项目的描述文件npm i json-server安装- 把对象字面量作为 HTTP Server 提供数据接口
这样不需要写复杂的后端代码,就能有一个 REST API 用。
12. 动态渲染表格:fetch + for 循环
前端写 common.js,先用空数组占位:
js
let users = [];
然后发请求取数据:
js
fetch('http://localhost:3000/users')
.then(data => data.json())
.then(data => {
users = data;
const oBody = document.querySelector('.table tbody');
let i = 1;
for (let user of users) {
oBody.innerHTML += `...表格行...`;
i++;
}
});
这里用 ES6 的 for...of 循环,不需要手动计数,可读性比传统 for (let i = 0; i < users.length; i++) 好很多。传统写法太机械了。
两种 for 循环的对比
javascript
// 传统计数器
// 快,CPU 计算规则;可读性差了点,太机械了
for (let i = 0; i < users.length; i++) {
let user = users[i];
}
// ES6 for...of
// js es6 新的for循环 不需要计数
for (let user of users) {
// 直接用 user,不用管 i
}
对比:
| 传统 | for(;;) | for...of |
|---|---|---|
| 速度 | 快(CPU 层面就是计数跳转) | 略慢(迭代器协议) |
| 可读性 | 差,“太机械了” | 好,意图清晰 |
| 需要索引时 | 天然有 i | 得自己额外声明 |
| 推荐场景 | 极致性能、需要 i | 日常遍历,优先用它 |
13. 总结一下
这套小东西跑起来,前后端分离的流程就清楚了。前端专注页面和布局,后端专注数据。模块化让代码好维护,语义化标签让结构更健康,DOM 编程让页面真正动起来。这些都是底层能力,值得反复练。