news 2026/9/8 16:09:30

Web-Dev-For-Beginners 银行应用(Bank App)示例解决方案:零框架 SPA 架构拆解与本地运行指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Web-Dev-For-Beginners 银行应用(Bank App)示例解决方案:零框架 SPA 架构拆解与本地运行指南

Web-Dev-For-Beginners 银行应用(Bank App)示例解决方案:零框架 SPA 架构拆解与本地运行指南

【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners

本篇技术指南围绕 7-bank-project 课程项目提供的“银行应用(Squirrel Banking)”完整示例解决方案展开,它使用纯 HTML5、CSS 与原生 JavaScript 构建(不依赖任何框架或库)。通过本文,你将掌握该解决方案的整体架构(模板与路由、登录/注册表单、数据层与状态管理)、本地快速启动方式(API 服务 +lite-server双端口运行),并从源码级理解每一层实现背后的设计意图,可直接用于把课程四个分节的知识串联成可运行的真实应用。

本仓库(7-bank-project)由微软 Web-Dev-For-Beginners 课程中的第 7 大主题“Build a Bank”构成,配套的英文示例解决方案说明见 7-bank-project/solution/README.md。本文所述的“示例解决方案”即 7-bank-project/solution 目录下的成品,它与课程四节内容一一对应:模板与路由、登录/注册表单、数据获取与使用、状态管理。

解决方案整体概览:你要运行的是什么

示例解决方案的定位一句话概括(引自英文 README 原文):

Example solution for the bank app project, built with vanilla HTML5, CSS and JavaScript (no frameworks or libraries used).

它本质上是一个无构建步骤的前端单页应用(SPA):所有页面结构以 HTML<template>形式静态声明,视图切换由一段极简 hash/History API 路由驱动,数据读写封装在独立的“伪 API”层,最终把账户与交易数据持久化到浏览器localStorage。整个前端由三份静态文件组成:

文件职责
7-bank-project/solution/index.html页面挂载点、登录/注册视图模板、仪表盘视图模板、交易弹窗模板与新增交易表单模板
7-bank-project/solution/styles.css设计令牌(design tokens)、明暗主题、布局与组件样式
7-bank-project/solution/app.js常量、格式化工具、数据层、状态管理、路由、认证与仪表盘逻辑、初始化入口
7-bank-project/solution/logo.svg应用品牌 Logo

最终的界面效果正是你在浏览器打开后会看到的两大页面——登录/注册页与账户仪表盘页:

银行应用登录与注册界面

银行应用账户仪表盘界面

启动前置条件与整体运行架构

在启动前端之前,先理解整个项目采用**双服务(双端口)**结构:

  1. API 服务:由 7-bank-project/api/server.js 提供的 Express 后端,监听端口5000,负责账户与交易数据存取。
  2. 前端静态服务:示例解决方案本身是纯静态文件,任何 Web 服务器均可托管;课程默认使用npx lite-server在端口3000启动开发服务器。

解决方案 README 的启动要求原文为:“First make sure you have the API server running”(确保 API 服务器已先运行)。API 服务的安装与启动方式详见 7-bank-project/api/README.md:进入api目录后执行npm install安装依赖,再执行npm start,服务器即开始监听5000端口。

需要特别说明的是:API 服务器会与前端服务器同时运行,请勿关闭(英文原文档明确指出 “This server will be running together with the main bank app server terminal (listening on port 3000), do not close it.”)。同时,API 的所有条目存储在内存中、不做持久化——服务一旦停止,全部数据即丢失;而前端当前实现则将账户数据镜像持久化在浏览器localStorage中,两种数据存储边界需要区分清楚(详见下文“数据层”章节)。

本地启动的完整步骤

结合英文原文档与仓库实际结构,完整的三步启动流程如下:

  1. 克隆仓库:将本仓库通过git clone拉取到本地,进入仓库根目录。

  2. 先启动 API 服务(终端 A):

    cd 7-bank-project/api npm install # 安装依赖,耗时取决于网络状况 npm start # 启动后监听 http://localhost:5000

    api目录中还提供了一份可交互的 REST 请求样例文件 7-bank-project/api/api.http,安装 VS Code 的 REST Client 扩展后可直接逐个发送请求验证接口。

  3. 再启动前端静态服务(终端 B):

    cd 7-bank-project/solution npx lite-server .

    该命令会以当前目录为根启动一个开发用 Web 服务器,默认监听端口3000。此时打开浏览器访问http://localhost:3000即可看到应用。

提示:由于需要运行 API,本地已必然装有 Node.js,因此 README 直接推荐npx lite-server .而不再额外要求安装任何静态服务器。若端口3000被占用,lite-server会自动尝试寻找下一个可用端口,请注意观察终端输出中的实际地址。

后端 API 一览:前端依赖的接口契约

虽然当前示例前端的最终数据层实现在本地完成(见下一节),但它预留了指向真实 API 的地址常量;API 的完整路由契约(见 7-bank-project/api/README.md 及 server.js 中每个处理器)如下:

方法路径说明
GET/api/获取服务器信息
POST/api/accounts/创建账户,示例请求体:{ user: 'Yohan', description: 'My budget', currency: 'EUR', balance: 100 }
GET/api/accounts/:user获取指定账户全部数据
DELETE/api/accounts/:user删除指定账户
POST/api/accounts/:user/transactions新增交易,示例请求体:{ date: '2020-07-23T18:25:43.511Z', object: 'Bought a book', amount: -20 }
DELETE/api/accounts/:user/transactions/:id删除指定交易

从 server.js 的源码可以印证几个实现细节:

  • 服务端口读取环境变量const port = process.env.PORT || 5000,可用PORT覆盖默认值;
  • 内存数据库db预置了一个演示账户test(货币符号$、余额75,含 3 条演示交易),方便 API 链路快速验证;
  • 账户创建接口对缺失参数返回400、账户重复返回409
  • 交易 ID 并非随机数,而是对date + object + amountMD5 哈希生成,同一笔交易重复提交会被409拒绝(去重设计);
  • CORS 白名单限定了http://(127.x.x.x|localhost)来源,保证本地双端口联调可用。

在 VS Code 中配合 7-bank-project/api/api.http(内含创建账户、查询、删除账户、添加/删除交易的完整示例)可以快速手工联调这组接口。

架构纵深:纯 JavaScript 如何支撑一个可用的 SPA

从源码结构看,示例解决方案没有使用 Vue/React 等框架,而是用四套自制机制完成了 SPA 的全部能力。这与课程四个分节的训练目标一一对应,是理解整个示例的最佳切入点。

1. 模板与路由(对应 1-template-route 课程)

所有“页面”以 HTML<template>元素静态声明在 index.html 中:

  • #login模板(index.html 第 25 行起):登录 + 注册双面板;
  • #dashboard模板(第 100 行起):余额摘要、交易表格、新增交易弹窗;
  • #transaction模板(第 211 行起):单行交易记录。

路由层在 app.js 中实现为一张表 +History API

const routes = { '/dashboard': { title: 'My Account', templateId: 'dashboard', init: refresh }, '/login': { title: 'Login', templateId: 'login', init: attachAuthHandlers } };

navigate(path)调用history.pushState写入 URL;updateRoute()根据当前路径取出对应<template>,克隆其内容并渲染进#app挂载点,随后执行该路由的init钩子;popstate监听器负责浏览器前进/后退。路由粒度非常轻——一套{ title, templateId, init }元数据即描述了一个页面。

2. 认证与表单(对应 2-forms 课程)

登录与注册逻辑位于 app.js:提交前先调用form.checkValidity()做浏览器原生校验,不通过则reportValidity();通过后读取表单字段,调用数据层接口,失败时将错误写入带role="alert"的错误容器,成功后updateState保存账户并navigate('/dashboard')跳转。

3. 数据层(对应 3-data 课程)

这是最值得留意的一处实现选择。当前示例的最终代码将数据访问全部封装成“可替换的伪 API”:

  • 常量serverUrl = 'http://localhost:5000/api'(app.js 第 5 行)注释为 “reserved for future server swap”(保留给未来切换真实服务端);
  • 具体实现getAccountcreateAccountcreateTransaction(app.js 第 90–170 行)则基于localStorage存取,并用setTimeout(60–80ms)模拟网络延迟,保持函数签名与将来替换为真实fetch调用一致。

例如createAccount会校验用户名非空、用户不重复,并对currency调用isIsoCurrency规范化;createTransaction生成uuid()作为交易 ID、累加账户余额并追加交易记录。这种“接口先行、实现可换”的结构,正是课程第 3 节“数据获取与使用”所训练的抽象思维落地。

4. 状态管理(对应 4-state-management 课程)

状态集中在 app.js:state对象通过Object.freeze保持不可变,任何更新都必须经updateState(property, newData)——它内部以{ ...state, [property]: newData }生成新对象并重新冻结,同时把活跃账户写入localStorage(key 为savedAccount)。此外还实现了两项进阶能力:

  • 跨标签页同步:监听全局storage事件,当其他标签页改动了账户/交易数据时,自动触发refresh()
  • Schema 迁移脚手架migrateSchema()读取schemaVersion,为将来数据结构升级预留了迁移入口(app.js 第 80–88 行)。

所有账户则保存在另一把 keyaccounts下,getAccounts/saveAccounts是仅有的两个读写入口,数据读取统一经safeParse兜底,避免脏 JSON 导致崩溃。

5. 仪表盘渲染细节

updateDashboard()(app.js 第 320–358 行)负责把状态渲染成界面:金额通过toCurrency()做本地化货币格式化,交易按日期降序排序后逐行克隆#transaction模板填充,正负金额分别挂上credit/debitCSS 类以便视觉区分。新增交易以无原生<dialog>的方式自行实现模态弹窗(.dialog+.show类),并具备完整的焦点管理:打开即聚焦日期输入框,Escape键关闭并归还焦点到“Add transaction”按钮——这符合 Web 无障碍指南中对话框键盘交互的要求。

无障碍与主题细节(styles.css 中的工程化实践)

7-bank-project/solution/styles.css 并非简单样式表,而是体现了若干值得借鉴的工程实践:

  • CSS 设计令牌--primary--surface--radius--space-*等自定义属性统一定义品牌色、中性色、圆角与间距(styles.css 第 5–48 行);
  • 随系统明暗自适应@media (prefers-color-scheme: dark)自动切换深色令牌组,<html contenteditable="false">【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 16:08:41

Day68-结构化Prompt设计:XML标签法/Markdown法/JSON Schema

一、为什么 Prompt 必须"结构化" Prompt 的本质是"自然语言版的接口契约"。如果不结构化&#xff0c;会出现 4 个真实的工程问题&#xff1a; 问题 表现 根因 解析失败 下游解析 JSON / Bean 时格式抖动 模型输出的边界不规范 难以 review PR 里 5…

作者头像 李华
网站建设 2026/9/8 16:08:31

C++20 ranges视图缓存陷阱:filter_view为何重复遍历结果异常?

前阵子帮同事排查一个数据清洗的 bug&#xff0c;现象特别诡异&#xff1a;一段用 std::ranges 写的过滤管道&#xff0c;第一次 for 遍历输出完全正常&#xff0c;第二次遍历同一个视图&#xff0c;第一个元素却凭空“多出来”了。同事第一反应是容器被谁改了&#xff0c;…

作者头像 李华
网站建设 2026/9/8 16:07:55

哪些项目适合AI做

不是所有问题&#xff0c;都需要 AI。比如&#xff1a;有无检测&#xff1b;尺寸测量&#xff1b;边缘定位&#xff1b;简单字符识别&#xff1b;规则形状判断。这些问题&#xff0c;如果光源稳定、位置固定、背景干净&#xff0c;用阈值、边缘、模板匹配这些方法&#xff0c;反…

作者头像 李华
网站建设 2026/9/8 16:05:34

网站分析工具怎么选?3大类15款工具全盘点

网站分析工具怎么选&#xff1f;答案不是看榜单&#xff0c;而是按“业务阶段 → 核心诉求 → 预算 → 工具组合”四步走。市面上的工具大致分成三类&#xff1a;免费基础监测款、SEO与竞品洞察款、企业级AI Agent平台。它们各自解决不同规模与预算下的问题&#xff0c;核心目标…

作者头像 李华
网站建设 2026/9/8 16:03:40

C++实现一笔画游戏:欧拉路径算法与图形渲染

1. 项目概述&#xff1a;C实现一笔画游戏的核心思路一笔画游戏是一种经典的逻辑益智游戏&#xff0c;玩家需要在不重复经过任何线条的前提下&#xff0c;用一笔连续画出整个图形。这个看似简单的游戏背后蕴含着欧拉路径的数学原理&#xff0c;而用C实现它则涉及图形渲染、算法设…

作者头像 李华