当前位置: 首页 > news >正文

前后端模块化分离实战:从零搭建用户列表展示(HTML+CSS+JS + json-server)

你是否也曾困惑:前端和后端到底怎么分开又怎么协作?
今天我们就从 0 到 1,手写一个用户信息列表页面。
后端用json-server模拟 REST API,前端用三件套(HTML + CSS + JS)实现动态渲染。
整个过程会涉及到:模块化思想、DOM 编程、fetch 异步请求、数组遍历……
全是干货,代码可直接运行。


一、最终效果预览

启动服务后,访问index.html,页面会从一个“假后端”http://localhost:3000/users拉取用户数据,并动态展示在表格中:

ID姓名昵称家乡
1lyg东理薛之谦南昌
2hy航哥南昌
3lqq橙帅信丰

(数据来源于db.json


二、项目结构与设计思想

我们采用前后端模块化分离的目录结构:

project/ ├── fe/ # 前端代码(实际可独立部署) │ ├── index.html │ └── common.js └── backend/ # 后端模拟 ├── db.json └── package.json

模块化的好处:

  • 每个文件职责单一,好维护

  • 前端只关心视图和交互,后端只关心数据接口

  • 方便以后扩展(比如把 json-server 换成真实后端)


三、后端准备:用 json-server 搭建零代码 API

1. 初始化项目

进入backend目录,执行:

npm init -y

得到package.json(项目描述文件)。

2. 安装 json-server

npm install json-server

3. 创建数据库文件db.json

写入以下内容(对象字面量作为数据源):

{ "users": [ { "id": 1, "name": "lyg", "hometown": "南昌", "nickname": "东理薛之谦" }, { "id": 2, "name": "hy", "hometown": "南昌", "nickname": "航哥" }, { "id": 3, "name": "lqq", "hometown": "信丰", "nickname": "橙帅" } ] }

4. 配置启动脚本

package.json中的"scripts"字段添加:

"scripts": { "dev": "json-server --watch db.json" }

解析--watch表示监听文件变化,自动重启服务。默认会开启http://localhost:3000,并提供/users等 RESTful 接口。

5. 启动后端

npm run dev

此时访问http://localhost:3000/users就能看到 JSON 格式的用户数据,一个完整的后端就“假装”好了。


四、前端页面:HTML + CSS 布局

1. 整体结构(语义化标签)

采用盒子模型思维:先划分盒子区域,再往里面填内容。
使用 HTML5 语义标签让结构更清晰:

<header>用户管理系统</header> <main class="container"> <aside>侧边栏(可留空)</aside> <div class="row col-md-6 col-md-offset-3"> <table class="table table-striped"> <thead>...</thead> <tbody><!-- 动态插入数据 --></tbody> </table> </div> <aside>右侧栏(可留空)</aside> </main> <footer>© 2025 全栈小练习</footer>

2. 引入 Bootstrap 快速美化

<head>中加入 Bootstrap CDN(Twitter 框架):

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
  • .container:固定宽度居中(PC 时代经典布局)

  • .row/.col-md-*:栅格系统,行列布局

  • .table.table-striped:表格斑马纹样式

注意:表格必须包含<tbody>标签,否则 JS 动态插入会找不到挂载点。

完整index.html代码如下(见文末汇总)。


五、DOM 编程与动态数据渲染

1. 理解 DOM 树

当浏览器解析 HTML 后,会生成一棵文档对象模型(DOM)树

  • document是整个文档的根对象

  • document.documentElement对应<html>

  • document.body对应<body>

  • 每个标签都是一个节点(Node),可以查询、修改、添加、删除

我们通过选择器找到表格的tbody节点,然后动态往里面插入行。

2. 使用 fetch 获取后端数据

common.js中编写:

fetch('http://localhost:3000/users') // 发起 GET 请求 .then(response => response.json()) // 解析 JSON 流 .then(users => { // 拿到用户数组,开始渲染 })
  • fetch是浏览器内置的 API,用于异步 HTTP 请求

  • 它返回一个 Promise,所以用.then()处理结果

  • 第一个.then()将原始响应转成 JSON 对象

  • 第二个.then()拿到真正的数据(数组)

3. 动态生成表格行

拿到users数组后,遍历每一个用户对象,构造<tr>并插入到<tbody>中。

const tbody = document.querySelector('.table tbody'); // 找到挂载点 let i = 1; for (let user of users) { tbody.innerHTML += ` <tr> <td>${i}</td> <td>${user.name}</td> <td>${user.nickname}</td> <td>${user.hometown}</td> </tr> `; i++; }

重点解析

  • document.querySelector():返回第一个匹配 CSS 选择器的元素

  • .innerHTML:可以获取或设置元素内部的 HTML 结构,我们使用+=追加内容

  • 模板字符串(反引号`...`)内部可以嵌入${变量},非常方便

  • for...of是 ES6 引入的遍历数组的语法,比传统for (let i=0; i<arr.length; i++)更简洁、可读性更强

为什么不直接用innerHTML = 完整字符串而要用+=
因为每次追加会保留原有的内容,否则会覆盖掉之前的行(本例中可接受,但更推荐先构建好一个完整字符串再一次性赋值,性能更好)。

4. 完整common.js

fetch('http://localhost:3000/users') .then(res => res.json()) .then(users => { const tbody = document.querySelector('.table tbody'); let i = 1; for (let user of users) { tbody.innerHTML += ` <tr> <td>${i}</td> <td>${user.name}</td> <td>${user.nickname}</td> <td>${user.hometown}</td> </tr> `; i++; } });

六、完整代码清单

1.backend/db.json

{ "users": [ { "id": 1, "name": "lyg", "hometown": "南昌", "nickname": "东理薛之谦" }, { "id": 2, "name": "hy", "hometown": "南昌", "nickname": "航哥" }, { "id": 3, "name": "lqq", "hometown": "信丰", "nickname": "橙帅" } ] }

2.backend/package.json

{ "name": "backend", "version": "1.0.0", "description": "模拟后端API", "main": "index.js", "scripts": { "dev": "json-server --watch db.json" }, "dependencies": { "json-server": "^1.0.0-beta.15" } }

3.fe/index.html

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>用户列表 - 前后端分离演示</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <header class="text-center" style="padding: 20px; background: #f5f5f5;"> <h1>用户信息管理</h1> </header> <main class="container" style="margin-top: 30px;"> <aside class="col-md-2"> </aside> <div class="col-md-8"> <table class="table table-striped table-bordered"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>昵称</th> <th>家乡</th> </tr> </thead> <tbody> <!-- JS 会动态填充数据 --> </tbody> </table> </div> <aside class="col-md-2"> </aside> </main> <footer class="text-center" style="padding: 15px; margin-top: 50px; background: #eee;"> © 2025 全栈练习 | 数据来自 json-server </footer> <script src="./common.js"></script> </body> </html>

4.fe/common.js

fetch('http://localhost:3000/users') .then(response => response.json()) .then(users => { const tbody = document.querySelector('.table tbody'); let index = 1; for (let user of users) { tbody.innerHTML += ` <tr> <td>${index}</td> <td>${user.name}</td> <td>${user.nickname}</td> <td>${user.hometown}</td> </tr> `; index++; } }) .catch(error => console.error('数据加载失败:', error));

七、运行步骤

  1. backend目录下执行npm run dev,保持终端不关闭(服务运行在3000端口)

  2. 用 Live Server 或直接打开fe/index.html(注意:直接打开文件会有跨域? json-server 默认支持 CORS,可以直接用file://协议访问,但更推荐用http-server或 Live Server 打开fe目录)

  3. 看到页面上的表格自动填充了数据库里的三条用户信息

如果数据没显示,打开浏览器控制台(F12)查看网络请求是否成功,确认http://localhost:3000/users能否正常访问。


八、知识点总结

技术点说明
模块化思想前端/后端代码分离,各自独立开发、维护,通过 HTTP 接口通信
json-server用 JSON 文件快速搭建 REST API,适合原型开发和学习
语义化标签header, main, footer, aside 等让 HTML 结构更清晰,SEO 友好
DOM 树HTML 被解析成节点树,document 对象提供查询和操作节点的方法
fetch API现代浏览器内置的异步请求方法,返回 Promise,替代古老的 XMLHttpRequest
innerHTML动态修改元素内部 HTML 的快捷方式(使用时注意 XSS 风险,本例无用户输入)
for...of简洁遍历数组的方法,直接获取每个元素的值,无需手动维护索引
模板字符串反引号 +${}语法,轻松拼接字符串和变量

九、拓展练习

  1. 增加用户:添加一个表单,通过fetch POST向后端新增用户

  2. 删除用户:给每一行加一个删除按钮,调用DELETE /users/{id}

  3. 改用 async/await:把.then()改成更现代的async/await写法

  4. 错误处理:在catch中显示友好的错误提示

大厂面试尤其关注 DOM 编程、模块化以及底层 HTTP 交互 —— 这些基础打好了,无论框架如何变化,都能快速上手。


写在最后
这篇笔记来自我的全栈学习过程,每一行代码都亲手敲过。
前后端分离不是高大上的概念,而是一种可以立刻实践的开发模式。
希望这篇文章能帮你迈出“既懂前端又懂后端”的第一步。

有任何疑问,欢迎在评论区交流 👏
如果你觉得有用,请点赞 ❤️ 或收藏 ⭐,让更多人看到~

http://www.jsqmd.com/news/987786/

相关文章:

  • 【干货】DeepSeek / 豆包数学公式完美转 Word 攻略!告别乱码,效率翻倍!AI 导出鸭一键快速转换公式
  • 从Keil到VScode的一站式服务(stm32和GD32)
  • VXGI未来发展方向:基于体素的全局光照技术路线图展望
  • 包包回收行业避坑总结,合肥 2026 连锁商铺诚信经营 - 奢侈品回收评测
  • 2026上海落户代办机构深度评测与避坑指南 - 新闻快传
  • C++:初始化列表
  • 【单智能体】AI健康与健身规划师 - 案例讲解(附完整源码)
  • 2026年吹膜机厂家推荐榜单:PE吹膜机/降解袋吹膜机/快递袋/背心袋/ABA共挤/全自动/小型/多层共挤吹膜机品牌实力精选 - 品牌发掘
  • 2026年上海注册公司代理记账哪家好?五大品牌深度测评与对比 - 新闻快传
  • 2026年展柜厂家推荐榜单:内衣展柜/酒柜/鞋柜/眼镜柜/珠宝展柜,专业定制与空间美学深度解析 - 企业推荐官【官方】
  • 宝塔面板如何设置网站伪静态 宝塔|Nginx网站部署 伪静态配置|静态资源访问配置
  • 2026东莞配眼镜镜片膜层工艺深度解析:防反射、耐磨、疏水三大镀膜技术详解 - 配眼镜新资讯
  • [AI Agent 01]对话记忆、Agent 循环、Function Calling
  • 2026年怎么降低论文AIGC率?7种高效方法必收藏!
  • ijkplayer vs ffplay.c:架构优化与工程实践深度解析
  • 2026年郑州机场货物人工搬卸公司权威分享报告:港区搬迁服务优选指南! - 品研笔录
  • 2026年 过滤/过滤器/高效过滤器/初效/中效/化学/活性碳/箱式过滤器厂家推荐榜单,G4/F5/F6/H13/H14高效空气过滤器实力品牌精选 - 品牌发掘
  • 【Redis分布式缓存实战】第22章 企业级Redis缓存项目架构复盘
  • 二、SCI常用逻辑词
  • 2026年北京刑事律师权威榜单TOP10:刑事案件辩护深度评估 - 新闻快传
  • 09Java 泛型
  • 郑州人注意!闲置迪奥包别乱卖,看完少踩坑 - 奢侈品回收评测
  • 2026年实测有效:4个指令+3个技巧助你把论文AI率从50%降到10%
  • 2026年哈尔滨系统门窗厂家推荐榜:家装/别墅/德式/极简/隔音/防渗漏/大玻璃品牌深度解析 - 企业推荐官【官方】
  • Web分布式网站架构之-Squid缓存【20260608】002篇-Squid 工作流程图
  • 三、SCI熟词生意(一)
  • 2026年 湿毛巾厂家推荐排行榜:一次性/酒店/餐饮/独立包装湿毛巾源头工厂,专业清洁与定制服务优选 - 品牌发掘
  • 斯坦福李瑞江团队在Nat Med发表能够融合病理切片与虚拟CODEX染色的多模态医学AI框架
  • 2026煤磨气体分析仪品牌盘点:防爆燃监测设备哪家强?全国厂家排名揭晓 - 品研笔录
  • OpenFeign 实战指南:微服务远程调用的优雅之道