零代码应用开发·第 7 章·3 学时

让它会存

数据存在哪里,决定这个应用能做到什么程度。

本章精髓 数据存在哪里,决定了这个应用能做到什么程度。写死在页面里,谁打开都一样;存进浏览器,只在这台机器上;要让所有人共用一份,靠双击打开的本地文件是做不到的。

学完本章后,你应该能够:

  1. 先画字段表再动手,说清一条记录由哪几个字段构成、各是什么类型;
  2. 做出增、删、改、查四种操作齐全的小工具,并设计好一条都没有时的样子;
  3. 在开发者工具里找到自己的数据,并说出它在硬盘上以什么形式存在;
  4. 说清本地存储的四条脾气:真实存在、位置由浏览器定、明文没加密、跟着浏览器走;
  5. 判断一个需求要落在三层存储的哪一层,并解释为什么这一版到不了第三层。
配套演示文件 第07章演示_记账本.html 第07章演示_没存下来.html 第07章演示_存储三层.html

先定字段表,再动手

成品 · 字段表 · 先要中间产物

这张表花五分钟,能省下后面两轮返工。

1.1本章成品:《这个月我花了多少》

记一笔支出:金额、分类、备注。列表显示,底部实时汇总。关掉浏览器再打开,记录还在。

打开 第07章演示_记账本.html 试一次,再打开 第07章演示_没存下来.html 试一次。两个页面长得一模一样,操作也一样,区别只在刷新之后:前者记录还在,后者一条不剩。这一章要补上的就是这个差别。

1.2字段表:一条记录长什么样

动手之前先回答一个问题:一条记录由哪几个字段构成,每个字段是什么类型,哪些必填。这张表定错,后面每加一个功能都要返工。

字段
类型
必填
说明
id
数字
这条记录的唯一编号,由程序生成,不给人填
金额
数字
保留两位小数,必须大于 0
分类
固定选项
餐饮/交通/学习/日用/其他,五选一,不让人手写
备注
文字
不超过 20 字,可以空着
时间
文字
记录时自动生成,不给人填
本章方法 填得出三条示例数据,字段表就出来了;填不出,说明还没想清楚要记什么。字段一改,界面、存储、列表、汇总都要跟着改,而在表上加一列只是一行字。

1.3本章新技巧:先要中间产物,再要成品

直接要成品,你只能在做完之后才发现字段设计错了。让它先交一张字段表,你确认了再往下走。

这个做法在往后每一次涉及数据的任务里都用得上:先要那份能一眼看懂、改起来只要一行字的中间产物,确认之后再要那份改起来要动一整页的成品。

中间产物拿得越早,返工的代价越小。字段表花五分钟,能省下后面两轮返工。

1.4可直接复制的提示词

发给 AI第一步 · 只要字段表,不要代码
我要做一个个人记账小工具,只给自己用,在电脑浏览器上打开。 请先只输出这份数据的字段表:每条记录包含哪几个字段、每个字段是什么类型、 哪些必填、哪些是固定选项(把选项也列出来)。 用表格形式,不要写任何代码。
发给 AI第二步 · 字段表确认之后再发
按上面确认的字段表生成页面,要求: 数据保存在浏览器的 localStorage 里,关掉浏览器再打开数据还在; 存储用的键名固定写成 myExpense2026,不要用 records、data 这类通用名字; 支持新增、删除、修改、查看四种操作,四种都要能用; 每条记录生成一个唯一编号,删除和修改都按这个编号定位,不按第几行; 列表按时间倒序;底部实时显示总金额; 一条记录都没有时,显示"还没有记录,点右下角添加",不要一片空白; 删除前要二次确认,确认框里写清删的是哪一条; 全部代码合并到一个 .html 文件,不引用任何外部资源,中文使用 UTF-8。
数据保存在浏览器的 localStorage 里
它把数据存在页面变量里,刷新一次全没了
键名固定写成 myExpense2026
用 records 这种通用名字,会和同一台电脑上别的作品互相覆盖
新增、删除、修改、查看四种都要能用
它常常只做新增和查看,改和删要逐个点名
按编号定位,不按第几行
按行号删,列表一排序就删错了那一条
一条记录都没有时,显示那一句话
第一次打开是一片空白,学生以为自己做坏了

1.5大模型的常见偏差

只做新增和查看 增删改查四种操作里,它默认给足的往往只有两种。四种要逐个写进需求,验收时也要逐个点一遍。
把数据存在页面变量里 页面上看着能记能删,一刷新全没了。这一条不写明 localStorage,出现的概率很高。
不做空状态 第一次打开是一片空白,没有任何提示。使用者分不清是还没有数据,还是这个东西坏了。
备用方案 现场生成不顺时,直接打开 第07章演示_记账本.html;对照实验用 第07章演示_没存下来.html,三层存储用 第07章演示_存储三层.html。三个文件都是现成的。

一条记录与四种操作 本章重点

字段 · 编号 · 增删改查 · 空状态 · 本地存储

本章的核心内容集中在这一部分和下一部分。

本章要学的术语 · 八个
01记录与字段record / field
02唯一标识id
03增删改查CRUD
04空状态empty state
05本地存储localStorage
06存储隔离origin isolation
07明文存储plain text
08前端·后端·服务器front end / back end

这八个术语会原样出现在浏览器面板、技术文档与产品说明中。前五个在本部分讲解,后三个在第三、四部分讲解。

2.1五个知识点,一个一个看

01记录与字段:一行一条,一列一项
金额
分类
备注
18.50
餐饮
食堂午饭
4.00
交通
公交

一行是一条记录,一列是一个字段

现象:列表里每一行长得一模一样,只是里面的字不同。

概念:一件事记一次,叫一条记录;记录里的每一项,叫一个字段。字段要先定好:有哪几个、各是什么类型、哪些必填。字段一改,界面、存储、列表、汇总都要跟着改。

类比:花名册。一行是一个人,姓名、学号、班级是三列。

02唯一标识 id:删的是哪一条,靠它认
按第几行删一排序就删错
按编号删怎么排都删对

编号跟着记录走,行号跟着排序走

现象:记两条一模一样的支出,删掉第二条,结果不见的是第一条。

概念:每条记录都要有一个别人没有的编号,叫唯一标识(id),由程序生成,不给人填。删除和修改都按编号定位。按第几行定位的程序,列表一排序就会动错那一条。

类比:点名按学号,不按站在第几排。队伍一动,排数就变了。

03增删改查:全世界的数据软件只有这四件事
记一笔
划掉一笔
金额填错了
看列表与汇总

四件事凑齐,这个工具才算能用

现象:记完一笔发现金额填错了,页面上却找不到能改的地方。

概念:对数据的操作只有四种:增、删、改、查,合称增删改查(CRUD)。这四个字母在数据库、后台系统、接口文档里到处出现。它默认给足的常常只有增和查,另外两种要逐个点名。

类比:账本上添一笔、划掉一笔、改一笔、翻回去看一笔。

04空状态:一条都没有的时候,页面什么样
没设计 一片空白以为坏了
设计了 一句提示加一个入口知道下一步做什么

第一次打开看到的就是这一屏

现象:刚做好的记账本第一次打开,中间一片空白,什么也没有。

概念:数据为零时的界面叫空状态。它是必须设计的一种状态,而不是"还没做完"的样子。空状态要写清两件事:现在没有东西,以及下一步该点哪里。

类比:空购物车不会只留一片白,它会写一句"去逛逛"。

05本地存储:浏览器给每个来源开的一个抽屉
记三笔关掉浏览器
重新打开三笔都在

这就是"存下来了"的意思

现象:关掉浏览器第二天打开,记的账还在。

概念:本地存储(localStorage)是浏览器给每个来源留的一格抽屉,存的是文字,关掉浏览器也不会丢。存进去要先打包成一段文字,取出来再还原。它只在这台机器的这个浏览器里,换一台电脑就是空的。

类比:浏览器给每个网站开的一个抽屉,抽屉钉在这台电脑上。换台电脑刷视频要重新登录,同一个道理。

2.2这就是存和取的那几行

整页一百多行,真正跟"存"有关的只有这几行。存进去要先打包成文字,取出来要还原成记录。

记账本.html节选 · 存、取、增、删
// 抽屉里的格子名。起一个别人不会重名的名字,这一行不是随手写的
var KEY = 'myExpense2026';

// 取:从抽屉里拿出那段文字,还原成一串记录;第一次打开时是空的
function load() {
  var s = localStorage.getItem(KEY);
  return s ? JSON.parse(s) : [];        // 没有就给一个空清单,不要让它崩
}

// 存:把一串记录打包成文字,放回抽屉
function save(list) {
  localStorage.setItem(KEY, JSON.stringify(list));
}

// 增:生成一个唯一编号,插到最前面
function add(amount, cat, note) {
  var list = load();
  list.unshift({ id: Date.now(), amount: amount, cat: cat, note: note, time: nowText() });
  save(list); render();
}

// 删:按编号筛掉那一条,不是按第几行
function del(id) {
  var list = load().filter(function (r) { return r.id !== id; });
  save(list); render();
}
var KEY = 'myExpense2026';
抽屉里那一格的名字。 起成 records、data 这类通用名,同一台电脑上的另一个作品会把你的数据覆盖掉
s ? JSON.parse(s) : []
第一次打开时抽屉是空的,给一个空清单。 少了后半句,第一次打开直接白屏,什么也点不了
id: Date.now()
用当前时刻的毫秒数当编号,两条记录不会重复。 不给编号,删除就只能按第几行,列表一排序就删错
filter(… r.id !== id …)
按编号筛掉那一条,剩下的重新存回去。 存回去这一步漏了,页面上看着删掉了,刷新一下它又回来了
一个专门的验法。记两条内容完全相同的,删第二条,看删掉的是哪一条。删对了,说明它是按编号定位的;删错了,说明它按的是行号。

把抽屉真的拉开看一眼

开发者工具 · 硬盘上的文件 · 明文

"存在浏览器里"这句话很虚。这一部分把它变成看得见的东西。

3.1办法一:按 F12,用浏览器自带的面板看

在记账本页面上按 F12,找到顶上那排标签里的应用(英文界面是 Application),左侧展开本地存储空间,点进去,右边就是一张两列的表。

键(Key)
值(Value)
myExpense2026
[{"id":1742031820451,"amount":18.5,"cat":"餐饮","note":"食堂午饭"…
myReading2026
[{"id":1742034411208,"book":"社会学的想象力","page":86…

左边那一列的名字,就是代码里 KEY 那个变量的值。所以两个作品各占一格,互不干扰。右边那一列,就是打包之后的那段文字,原样躺在这里。

这个面板不只能看,还能改。双击右边的值可以直接编辑,选中一行按删除键可以删掉整格。把值改坏了再刷新页面,是检验程序有没有设默认值的最快办法:写得好的会当成空数据从头开始,写得差的直接白屏。

3.2办法二:到硬盘上把那个文件找出来

浏览器不是把数据变没了,它落在一个真实存在的文件夹里。以 Windows 为例,把"你的用户名"换成自己的:

存的是什么
在硬盘上的位置
Chrome 的抽屉
C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data\Default\Local Storage\leveldb\
Edge 的抽屉
把上面路径中间的 Google\Chrome 换成 Microsoft\Edge,其余一样

两个浏览器的路径只差中间那一段厂商名。这一眼就能看懂什么叫存储隔离:它们压根就是两个文件夹。

AppData 默认是隐藏的,不用去改系统设置:把上面那行路径复制进文件资源管理器的地址栏,回车就能进去。

进去之后看到的是一堆名叫 000005.log、CURRENT、LOCK、MANIFEST 的文件,没有一个叫"我的记账本"。这里存的不是一人一份的文档,而是一个数据库,你在这个浏览器里打开过的所有页面,存的东西全在这几个文件里混着。

用记事本打开最大的那个 .log 文件,会看到一片乱码里夹着能读的字:myExpense2026、金额、分类、备注。那几段就是你的数据。

你的账确实是以明文躺在硬盘上的。没有加密,谁能打开这台电脑,谁就能读到。本地存储方便,但它不等于安全。
要在硬盘上看这些文件,先把浏览器完全退出。否则要么打不开,要么看到的是旧内容。那个 LOCK 文件就是干这个的。
讨论知道数据是明文存在本机之后,你还愿意用这个记账本记真实的账吗?换成一个记密码的工具呢?两者的差别在哪里?

3.3另外两个知识点

06存储隔离:抽屉是按来源分格的
Chrome 的抽屉Edge 打不开
这台电脑换台电脑是空的
所有本地文件共用 file:// 这一格

前两条是隔离,第三条是不隔离

现象:同一个作品,在另一个浏览器里打开是空的。而同一台电脑上两个不同的作品,数据却会互相覆盖。

概念:抽屉按来源分格:不同浏览器各一套,不同网站各一格。但所有双击打开的本地文件共用 file:// 这一格,靠键名互相区分,不靠文件名。

类比:两家银行各有各的保险库,而同一个库里的格子只靠编号区分,谁的编号重了谁倒霉。

07明文存储:能打开这台电脑的人就能读到
…ìOÊ
myExpense2026
[{"amount":18.5,"cat":"餐饮"…
âÜ\x00LOG…

乱码里夹着能读的字,那几段就是你的数据

现象:用记事本打开那个 .log 文件,能直接读出自己记的金额和备注。

概念:本地存储的数据是明文保存的,没有加密。方便和不安全是同一件事的两面。凡是不愿意被别人看到的内容,不要交给它。

类比:写在便签上贴在桌面,随手可取,也随眼可见。

3.4三个紧接着会冒出来的问题

能让它存到我作品所在的文件夹里吗
不能
网页无权决定自己的数据落在硬盘哪儿。真让网页随便往硬盘写文件,那随便打开一个网页都可能改你的东西
把那几个硬盘上的文件发给同学,他能看到我的账吗
基本不能,也不该这么干
那是整个浏览器的数据库,跟浏览器版本和用户目录绑在一起
把 .html 发给同学,他打开是空的,是不是出错了
不是出错
作品和数据是分开的两样:作品是那个文件,数据在浏览器的抽屉里。这正是本地存储的定义

想让数据也过去,正路只有一条:让应用自己把数据吐出来,变成一份你拿得动的文件,发过去,对方用导入功能读进他自己的抽屉。真实世界里的本地工具,笔记软件、密码管理器、单机游戏存档,走的全是这条路。上机的选做就是加这个功能。

把这一部分连起来,本地存储的脾气就是四条:它在硬盘上真实存在、位置由浏览器说了算、明文没有加密、跟着浏览器而不跟着你的文件。知道这四条,就知道什么东西可以放心交给它,什么东西不行。

三层存储与前后端

写死 · 本机 · 服务器

你的需求要落在哪一层,决定了这件事做不做得成。

4.1数据可以存在三个地方

打开 第07章演示_存储三层.html,选一种存法,再选一种情境,页面会告诉你数据还在不在。三种存法的脾气,一次就试完了。

第一层
写死在页面文件里
谁打开都一样,改内容要改代码
课程列表、专业介绍这类只读的东西
第二层
存进这台机器的浏览器
本机记得住,换台电脑就是空的
本章的记账本、读书记录,单人自用的工具
第三层
存到一台服务器上
所有人共用一份,谁改了别人都看得到
班费账本、报名表、需要多人协作的东西

第三层这一版到不了。你在你的浏览器里记,我在我的浏览器里记,两边之间没有任何通道。这条边界不是缺陷:单人用的工具,第二层足够。

4.2第八个知识点

08前端与后端:为什么"全班共用一份"需要一台服务器
前端你屏幕上这一份
服务器全天开机的那台
别人的前端他屏幕上那一份

两个人之间要有一个共同的中转站

现象:手机上的外卖软件,打开要联网,换个手机登录后订单还在。

概念:你看得见、点得到的那一部分叫前端;替所有人保管数据、处理请求的那一部分叫后端,跑在一台全天开机、有固定地址的计算机上,那台机器叫服务器。多人共用一份数据,必须经过这个中转站。

类比:各自的抽屉,和教室前面那块公共黑板。要让全班都看到,只能写在黑板上。

怎么判断一个软件的数据在第几层,有三个现象可以看:打开要不要联网、提交要不要联网、换台设备登录数据还在不在。三个都是要,那它的数据在服务器上,不在你的手机里。

讨论如果这是一个班费记账本,班长记账、全班查看,本章的做法差在哪一层?要补上哪一样东西才做得成?

4.3前沿三分钟:数据存在哪里,是一道选择题

每章固定栏目 · 一条与当章内容相关的行业动态

这几年有一类做法重新流行起来,叫"本地优先":数据首先存在使用者自己的设备上,联网只用来同步,断网照样能用。笔记软件、待办工具、白板应用里都能看到这条路线。

它对着的是另一种默认做法:数据全部放在服务商的服务器上,断网就打不开,服务停了数据也就跟着没了。本地优先的主张很简单:你的东西应当先在你手上。

两条路各有代价,本地优先换来断网可用与数据自持,代价是多设备同步要自己想办法。所以"数据存在哪里"不是技术高低,而是一道选择题:你做的东西,给一个人用,还是给一群人用。

上机实验 作业 2

三选一 · 字段表 · 四种操作

上机环节由此开始,本次上机的成果就是作业 2,当堂完成并提交。

5.1三个题目,任选其一

题目 A
这个月我花了多少

个人记账:金额、分类、备注,列表加实时汇总。

通用
题目 B
我的读书记录

书名、进度、短评、评分,列表加已读本数统计。

偏文科
题目 C
实验批次记录本

批次号、条件、结果、备注,列表加按条件筛选。

偏理工

三个题目都要求增删改查四种操作齐全有空状态关掉浏览器再打开数据还在。允许更换题材,验收标准不变。

5.2上机六步

1
先写字段表,暂时不要用大模型
每个字段:叫什么、什么类型、必填与否、是不是固定选项。填得出三条示例数据才算写完
产出:一张字段表
2
让它先交字段表,和自己那张对一遍
对不上的地方当场改定,例如把一个填空字段改成固定选项
产出:确认过的字段表
3
按确认的字段表生成并另存
键名要起一个别人不会重名的,不要用 records、data
产出:一个能打开的工具
4
四种操作各点一遍,每种截一张图
增、删、改、查。删的时候用那个专门验法:记两条一样的,删第二条,看删掉的是哪一条
产出:四张操作截图
5
三个存储实验,各截一张图
刷新一次数据还在、关掉浏览器重开数据还在、换一个浏览器打开是空的
产出:三张实验截图
6
按 F12 打开应用面板,找到自己的那一格
截一张能看清键名和值的图。把值改坏再刷新,看程序有没有当成空数据从头开始
产出:面板截图与一句结论

5.3共同验收标准

字段表齐全 每个字段写清类型、必填与否、是不是固定选项 照着表,在成品上逐个字段指出来
增删改查四种都能用 四种操作在界面上都找得到入口 四种各点一遍,都要有反应
删的是你点的那一条 按编号定位,不按第几行 记两条完全相同的,删第二条,看删掉的是哪一条
刷新之后数据还在 这是本章的及格线 按 F5 刷新一次,看列表还在不在
关掉浏览器重开数据还在 真正存进了抽屉,不是页面变量 完全退出浏览器,重新打开这个文件
一条都没有时有提示 写清现在没有东西,以及下一步点哪里 把记录全删光,看那一屏是什么样
键名不是通用词 不用 records、data、list 这类名字 在代码里找到那一行,看名字够不够特别
断网也能用 不引用任何网上的资源 断开网络连接刷新,再记一笔

5.4常见错误与处理

刷新一次数据全没了
数据存在页面变量里,没进抽屉
写明"保存在 localStorage 里,关掉浏览器再打开数据还在",重新生成
只有新增和查看,改和删找不到
四种操作没有逐个点名
补一句"新增、删除、修改、查看四种都要能用"
删掉的不是点的那一条
按第几行定位,列表一排序就错位
要求每条记录生成唯一编号,删改都按编号
页面上删掉了,刷新又回来
改了内存里的清单,没有存回抽屉
要求每次增删改之后都重新写入一次
第一次打开是一片空白
没设计空状态
补一句"一条记录都没有时显示提示与入口"
同学的作品把我的数据覆盖了
两个作品用了同一个键名,本地文件共用一格抽屉
把键名改成一个别人不会重名的,例如加上自己的学号
发给同学,他打开是空的
这不是出错,作品和数据本来就是分开的两样
要让数据也过去,做一个导出与导入功能,见选做
数据删了想找回来
这一版没有回收站
验收时用示例数据,不要拿真实账目试

5.5提交内容

字段表
每个字段的名称、类型、必填与否、固定选项
写在作业文档最前面
作品文件
一个 .html,断网可用
单个文件,不要压缩
操作与实验截图
增删改查四张,加刷新、重开、换浏览器三张,再加空状态一张
八张截图各配一句说明
应用面板截图
能看清键名和值,附一句"把值改坏后刷新会怎样"
截图加一句结论
作业 2 评分
占比
字段设计与数据结构:字段表齐全,类型与必填交代清楚
30%
四种操作完整可用:增删改查都能用,删改按编号定位
40%
状态与体验完整度:空状态、二次确认、刷新与重开都不丢数据
30%

提交方式:按教师提供的作业模板(Word)填写,文档开头注明所选题目。提交渠道见课堂通知。当堂提交。

5.6再进一步(选做)

给你的工具加一对导出与导入:导出把当前所有记录变成一段文字或一个文件,导入把它读回来。

加完之后,把导出的那段东西发给同组同学,让他在自己的电脑上导入。这是本地存储唯一的正路:数据不会自己跟着作品走,要让应用把它吐出来,你才拿得动。

本章小结
本章五条结论
  1. 先定字段表,再动手。一条记录有哪几个字段、各是什么类型、哪些必填。填得出三条示例数据,这张表就出来了。
  2. 对数据的操作只有四件事:增、删、改、查。它默认给足的常常只有增和查,另外两种要逐个点名;删和改一律按编号定位,不按第几行。
  3. 空状态是必须设计的一种状态。一条记录都没有的时候,要写清现在没有东西,以及下一步该点哪里。
  4. 本地存储的脾气有四条:硬盘上真实存在、位置由浏览器说了算、明文没有加密、跟着浏览器而不跟着你的文件。
  5. 数据存在哪里,决定这个应用能做到什么程度。要让所有人共用一份,必须有一台服务器当中转站,这一版到不了那一层。
本章脉络