简介:Delphi Web前端开发教程以TMS WEB Core框架为主线,面向希望用Delphi或Lazarus快速进入Web应用开发的初学者与进阶开发者,也适合传统Delphi程序员补齐前端与跨平台发布知识。教程从Delphi/Object Pascal的历史与现状讲起,梳理IntraWEB、uniGUI与TMS WEB Core等Web框架的特点,再进入环境配置、项目设置、Pas2JS编译、RTL运行时库、页面设计、调试及部署分发等环节,兼顾概念理解与动手实践。目录还覆盖Web开发基础知识、第三方框架比较、预处理器、命令行编译与实用函数等专题,便于读者按知识模块查漏补缺。资源包仅含1个PDF文件,约3.84MB,便于离线阅读和按目录查阅;内容涉及渐进式Web应用、Electron桌面应用与Miletus桌面应用等创建方式,可帮助读者建立从桌面到Web、移动端的完整开发路径。目前已有5029人学习,适合作为TMS WEB Core入门与框架选型的系统参考资料,也可用于企业内部培训前的基础铺垫。
1. 先弄明白一件事:Delphi 写网页到底是怎么一回事
不少人第一次听到「Delphi Web 前端开发」,第一反应是:这不是做 Windows 窗口程序的工具吗?某公司内部培训上就有这样的场面——写了七八年 Object Pascal 的同事被安排做后台管理页面,打开浏览器开发者工具看了十分钟就关掉,说这活儿干不了。他缺的不是编程能力,是没人告诉他:这条路已经被 TMS WEB Core 铺好了。
说白了,这门技术教的是用你熟悉的 Pascal 写浏览器能直接打开的网页。窗体上拖个按钮、写段事件代码,框架负责把它翻译成 HTML 和 JavaScript,产出的是纯静态文件,丢到任何托管服务器就能访问。它适合手上有 Delphi 基础、一碰前端就发怵的人,也适合零基础、想找条不那么挤的入门路的人。
2. 为什么值得学:一套 Pascal 代码跑遍网页、桌面和手机
2.1 从「只会做桌面窗口」到「能交付网页」的距离有多远
先说一个很多人没意识到的事实:你现有的 Delphi 技能,绝大部分是可以直接搬过来的。变量声明、类、属性、事件、异常处理、单元文件组织方式,这些在 TMS WEB Core 里都没变。真正变的只有一层,就是「东西画在哪儿」。
你可以这样理解:以前你在 Windows 的窗体画布上摆控件,Windows 负责把按钮画成按钮;现在你在 TMS WEB Core 的窗体设计器里摆同样的控件,框架负责把 TWebButton 渲染成浏览器里真实的按钮元素。你在 Object Pascal 里写的事件处理代码,编译后变成 JavaScript 跑在浏览器里,用户点一下按钮,那段代码就执行。
我第一次接触的时候,最大的心理障碍是「我不懂前端」。后来发现,入门阶段根本不需要你手写 HTML 和 CSS,框架已经把常用控件封装好了。教程目录里那一长串 TWebLabel、TWebButton、TWebEdit、TWebComboBox、TWebMemo、TWebProgressBar,本质上就是你在 VCL 里用惯的那些控件的 Web 版本,属性名、事件名都对得上号。你会用 TEdit,就基本会用 TWebEdit。
还有一层价值在于覆盖面。同一套代码思路,可以产出浏览器直接访问的 Web 应用、可以做成渐进式 Web 应用(PWA),也可以套一层壳变成 Windows 或 Mac 上的桌面程序,甚至能往移动端走。对个人开发者和小团队来说,这意味着不用为了「再做个网页版」重新学一门语言、重写一遍业务逻辑。
提示:入门阶段别急着研究底层怎么转译。先把一个按钮点下去、标签数字变一下这个闭环跑通,信心比原理重要。
2.2 TMS WEB Core 和 IntraWEB、uniGUI 到底差在哪
教程原文把 Delphi 的 Web 开发方案叫「三剑客」:IntraWEB、uniGUI、TMS WEB Core。三个都能让你用 Pascal 做 Web,但思路完全不同,选错了后面会很别扭。
一句话区分:前两个是「服务端帮你画页面」,TMS WEB Core 是「把 Pascal 编译成前端代码,让浏览器自己跑」。
| 对比项 | IntraWEB | uniGUI | TMS WEB Core |
|---|---|---|---|
| 代码实际跑在哪 | 服务端进程 | 服务端进程 | 浏览器里 |
| 浏览器收到什么 | 服务端生成的页面 | 服务端生成的页面加脚本 | 纯 HTML 加 JS 静态文件 |
| 部署要求 | 服务端程序必须常驻 | 服务端程序必须常驻 | 任意静态托管空间 |
| 用户量上来之后 | 服务端压力跟着涨 | 服务端压力跟着涨 | 压力主要在浏览器和带宽 |
| 适合什么场景 | 内网管理系统 | 内网业务系统 | 对外网站、Web 应用、可离线应用 |
这个差别在实际项目里非常具体。用前两个方案,你的程序必须跑在一台服务器上,用户每次操作都要跟服务器来回通信,服务器挂了页面就打不开。用 TMS WEB Core,编译出来就是一堆 html、js、css 文件,扔到任何静态托管上就能用,没有后端进程要维护,也不存在「服务端崩了全员停摆」这种事。
教程里提到的「无需二进制文件、可执行文件」,讲的就是这个。你交付的不是一个 exe,而是一个文件夹。
2.3 纯 HTML/JS 输出这件事,对你意味着什么
「第一个能生成真正 100% WEB HTML/JS 应用程序的 Delphi 框架」——这句话第一次看有点营销味,但拆开看确实是个硬差别。
第一层意思是交付变简单了。传统 Delphi 项目发布,你得考虑目标机器有没有运行库、要不要装依赖、32 位还是 64 位。Web 项目发布,你把编译产物整个目录传上去,用户用浏览器打开就行,跨平台问题直接消失了——Windows、Mac、Linux、手机,浏览器能开就能用。
第二层意思是调试方式变了。你在 IDE 里按运行,程序在浏览器里打开,你可以直接开浏览器自带的开发者工具看网络请求、看控制台报错、改 CSS 看效果。教程里专门有一节讲调试和实时预览,这个能力入门阶段一定要早点用起来,比闷头猜错误快十倍。
第三层意思是它带来了一些新概念。教程里提到的 REST API、云数据库、HTML 模板、JavaScript 和 CSS 混用,都是传统桌面开发里不太会遇到的东西。别被这些词吓住,它们只是「数据从哪来」和「页面长什么样」这两件事的不同解法,后面第 3 章会用大白话一个个过一遍。
注意:纯前端意味着你的数据库密码、密钥这类东西绝对不能写在前端代码里。涉及敏感数据的操作,必须走服务端接口。这个坑新手极容易踩,后面避坑那一章还会展开讲。
3. 动手前的地基:零基础也能听懂的几个 Web 概念
3.1 HTML、CSS、JavaScript 三件套分别管什么
把网页想象成一个人:HTML 是骨架,决定了有哪些部件、部件之间怎么嵌套;CSS 是衣服和妆容,决定颜色、大小、位置、圆角、阴影;JavaScript 是肌肉和神经,决定点一下会发生什么、数据怎么变。
你写 TMS WEB Core 的时候,其实是在跟这三样打交道,只是被框架包了一层。你在窗体上放一个 TWebButton,框架最后生成的是一个 button 元素,这是 HTML 的活;你给按钮设颜色、设宽度,最后变成一段样式规则,这是 CSS 的活;你双击按钮写 WebButton1Click 事件,最后变成一段绑在点击事件上的 JS 函数,这是 JavaScript 的活。
入门阶段你不需要手写这三样,但需要知道它们存在、知道出了问题去哪看。举个例子,页面上的按钮位置不对,你去翻 Pascal 代码是找不到原因的,那是 CSS 的事;点了按钮没反应,去浏览器控制台看有没有红色报错,那是 JavaScript 的事。建立这个「问题归属」的判断,比记住语法重要得多。
教程里提到的绝对定位和相对定位,本质上就是 CSS 定位方式的两种选择。绝对定位是你把控件拖到哪儿它就固定在哪儿,像素级精确,适合做固定布局的界面;相对定位是控件跟着页面流走,窗口变窄会自动换行,适合内容长度不定的页面。新手容易一上来全用绝对定位,桌面端看着挺好,用户手机上一打开全挤在一起,这是血泪经验。
3.2 Pas2JS:Pascal 是怎么变成浏览器能跑的代码的
浏览器只认 JavaScript,不认 Pascal。中间那个翻译官就是教程里提到的 Pas2JS 编译器。
它的工作方式可以类比成翻译整本书,而不是同声传译:你在 IDE 里点编译,Pas2JS 把你的 Pascal 单元一次性翻成 JS 文件,然后浏览器加载这些 JS 去执行。所以你写完代码必须重新编译才能在浏览器里看到效果,改一行跑一次,这点跟传统 Delphi 开发习惯一致。
除了翻译语法,Pas2JS 还需要一套运行时库来支撑那些 Delphi 里司空见惯的东西,比如字符串处理、日期时间、集合、异常。教程里提到的 RTL 运行时库就是干这个的。你在代码里写 FloatToStr、StrToFloatDef、FormatDateTime 这些函数,编译后并不会凭空消失,而是对应到运行时库里的实现。知道这一点,你就不会奇怪为什么最终产物里除了你自己的代码,还有一堆别的 js 文件。
教程里还提到预处理器和命令行编译。预处理器简单理解就是「编译前先做一遍文本替换」,常见的用法是区分调试版和发布版;命令行编译则是让构建过程可以写进脚本,不用每次开 IDE 手动点。这两样入门时可以先跳过,等你能独立做完一个页面再回头看,会突然觉得有用。
3.3 Application、Form、Frame 三个对象先认个脸
这三个是 TMS WEB Core 里最基础的对象,搞混了后面会很乱。
Application 是应用级别的对象,整个网页程序只有一个。它管的是全局的事:程序什么时候启动、什么时候结束、全局的配置和状态放哪儿。你在里面写的初始化代码,页面一加载就会执行。
Form 是窗体,也就是一个页面或者一个页面里的一个窗口。你用设计器拖控件,拖的就是拖到某个 Form 上。多页面的应用会有多个 Form,可以在运行期创建,也可以把 Form 嵌到别的控件里托管显示。教程里专门讲了运行期创建窗体和在其它控件中托管窗体,这两种做法在单页应用里用得非常多。
Frame 是框架,可以理解成「可以复用的界面片段」。比如你的系统每个页面顶部都有一条导航栏,与其在十个 Form 里各画一遍,不如做成一个 Frame,每个 Form 里放一份。以后导航栏要改,只改 Frame 一处,所有页面跟着变。
用一句话记住层级:Application 管全局,Form 管一个页面,Frame 管一段可复用的界面。新手常见错误是把全局状态塞进 Form,结果换页面就丢了;也有人把所有东西都堆在 Application 里,最后代码没法维护。分清职责,从一开始就养成习惯。
4. 第一个能跑的例子:半小时做出一个会算数的网页
4.1 装环境:社区版加框架试用版
教程摘要里写得很清楚:学这个只需要免费的 Delphi 社区版,加上 TMS WEB Core 的试用版,够用了。这句话对新手很重要,意思是你不必先掏钱买授权才能开始。
安装顺序建议是这样:先装 IDE,装完打开确认能新建一个普通桌面项目并运行,说明基础环境没问题;然后装 TMS WEB Core,装完重启 IDE,看新建项目对话框里有没有出现 Web 相关的项目模板。有,就说明装好了。
如果你用的是 Lazarus,教程里也有对应章节。Lazarus 是开源方案,安装过程和 Delphi 不一样,但装完之后的操作思路是相通的。新手我不太建议一上来就折腾 Lazarus,先把 Delphi 社区版这条路走通,遇到问题搜出来的资料也多一些。
提示:装完先别急着写代码,花五分钟把 IDE 里的项目模板列表翻一遍。教程里提到有普通 Web 应用、渐进式 Web 应用、Electron 桌面应用、Miletus 桌面应用几种模板,先知道它们存在,以后要做什么心里有数。
4.2 新建项目:选对模板,看清目录结构
新建项目的时候选最基础的那个 Web 应用模板,别一上来就选 PWA 或者桌面壳,那些等你能做出一个能跑的页面再说。
创建完成后,你会看到两类东西。一类是设计器里的窗体,长得跟你熟悉的桌面窗体差不多,可以拖控件、调属性;另一类是项目里的文件,包括 Pascal 单元、一个 HTML 模板文件,还有若干配置。教程里提到「使用 HTML 模板」「自动同步 HTML 模板」,意思是你可以在模板文件里写一些静态的骨架,同时框架会负责把设计器里的控件对应上去。
这里有个容易懵的点:设计器里看到的布局和浏览器里最终的样子可能不完全一样。因为设计器只是一个可视化编辑环境,真正决定外观的是最终生成的 HTML 和 CSS。看到不一致先别慌,运行起来在浏览器里看,以浏览器为准。
项目设置里还有一些跟版本、路径相关的选项。教程里有「配置项目设置」「自动化版本管理」这样的章节,这些属于进阶内容,第一次做例子时用默认值就行,不用每项都改。
4.3 拖三个控件,写第一段 Pascal 事件代码
现在开始真正的第一步。在窗体上做三件事:
- 放两个 TWebEdit,分别命名为 WebEdit1 和 WebEdit2,用来输入两个数字。
- 放一个 TWebButton,命名为 WebButton1,Caption 属性改成「算一下」。
- 放一个 TWebLabel,命名为 WebLabel3,Caption 清空,用来显示结果。
然后在设计器里双击这个按钮,IDE 会自动跳到代码编辑器,并生成一个空的事件方法。往里填下面这段:
procedure TForm1.WebButton1Click(Sender: TObject); var NumA, NumB, Sum: Double; begin // StrToFloatDef 的第二个参数是"转换失败时的兜底值" // 用户什么都没输的时候,这里会拿到 0,而不是直接报错崩溃 NumA := StrToFloatDef(WebEdit1.Text, 0); NumB := StrToFloatDef(WebEdit2.Text, 0); Sum := NumA + NumB; // 把结果写回标签的 Caption,浏览器里会立刻刷新 WebLabel3.Caption := FloatToStr(Sum); end;逐段说清楚这段代码在干什么。
NumA, NumB, Sum: Double声明了三个双精度浮点变量,分别装第一个数、第二个数和结果。用 Double 而不是 Integer,是因为用户可能输入小数,用整数类型会把小数部分截掉。
StrToFloatDef(WebEdit1.Text, 0)是「把文本转成数字,转不了就用 0」。这里为什么不直接写 StrToFloat?因为用户可能什么都没输,或者输了一堆字母,直接转会抛异常,在浏览器里表现为页面报错、按钮点了没反应,对新手来说极难排查。用带默认值的版本,是最省事的防呆写法。
WebLabel3.Caption := FloatToStr(Sum)把数字转回文本,赋给标签。TWebLabel 的 Caption 属性就是它显示的内容,改了这个属性,浏览器里立刻跟着变。这种「改属性就更新界面」的机制,跟你以前做桌面程序完全一样。
4.4 点运行之后发生了什么:编译、预览与产物
按下运行,会发生几件事,值得你花两分钟搞清楚。
第一步,Pas2JS 把你的 Pascal 单元编译成 JavaScript 文件。第二步,IDE 启动一个本地服务或者打开一个本地文件,在浏览器里加载页面。第三步,页面加载时 Application 对象初始化,你的 Form 被创建,控件被渲染成对应的 HTML 元素。第四步,你点按钮,那段编译后的 JS 函数执行,标签内容更新。
如果按钮点了没反应,按这个顺序排查:先在浏览器里打开开发者工具的控制台,看有没有红色报错,有的话大概率是代码写错了,比如控件名字拼错;没报错但没反应,检查按钮的 OnClick 事件是不是真的绑上了,设计器里选中按钮看事件页;还有一种情况是标签更新了但你没看见,因为标签宽度是 0 或者被别的控件挡住了。
教程里提到的「实时预览」是个很省时间的功能,改完样式不用重新编译就能看到效果。但要注意,它主要针对外观调整,逻辑代码改了还是得重新编译运行才有变化。这一点我当初搞混过,改了半天 Pascal 代码页面没反应,以为软件坏了。
等这个例子跑通了,你可以试着改一改:把加法改成乘法,加一个清空按钮,把两个输入框换成 TWebSpinEdit 让用户只能选数字。每改一次跑一次,这种小步快跑的感觉,比看十页文档管用。
5. 新手最容易翻车的五个地方:避坑清单
5.1 装环境和新建项目阶段的坑
现象一:新建项目对话框里找不到 Web 项目模板。原因通常是框架装了但 IDE 没重启,或者装的时候版本对不上——IDE 是这一个版本,框架装到了另一个版本的目录里。解决方式很直接:完全关掉 IDE 再打开,还不行就重装框架,装的时候看清楚它问你要往哪个 IDE 版本里装,多个版本共存时尤其容易选错。
现象二:项目能新建,一运行就报一堆找不到单元的错误。原因是项目搜索路径里没有包含框架的源码目录。你新建的是空项目,或者从别的地方拷来的项目,路径配置没跟过来。解决方式是打开项目选项,检查搜索路径里有没有框架的库目录,缺了就补上,补完重新编译一次。
现象三:同一个项目,在自己的电脑上跑得好好的,拷给同事就打不开。原因是路径里带了绝对路径,或者依赖了本机特定位置的配置文件。解决方式是把项目里所有路径改成相对路径,并且养成「拷贝整个项目目录」的习惯,别只拷 pas 文件。
5.2 写代码和调试阶段的坑
现象四:代码逻辑没错,但界面上就是没变化。原因很可能是改了控件属性却没触发重绘,或者你改的是设计期属性、运行期被别的代码覆盖了。解决方式是先确认改动发生在运行期并且确实执行到了那一行,必要时在中间加一句往标签写调试信息的代码,看执行流到底走到哪儿。另外,改了 Pascal 代码一定要重新编译,实时预览看的是外观不是逻辑。
现象五:功能在自己电脑上正常,发给别人用就出问题。常见原因有两个,一是用了只在本地有效的地址或者端口,二是把密钥、数据库地址这类敏感信息直接写在了前端代码里。前者改成相对路径或者可配置项,后者必须挪到服务端接口后面。前端代码是明文交付给浏览器的,任何人打开开发者工具都能看到,这一点跟传统桌面程序完全不同,务必记住。
现象六:控件拖得整整齐齐,用户手机上一打开全乱了。原因是全程用了绝对定位,控件位置是写死的像素。解决办法是给主要容器改用相对布局,或者至少给页面设一个最小宽度、允许横向滚动。教程里讲绝对定位和相对定位那两节值得反复看,这不是理论,是直接影响用户能不能用的东西。
注意:这一章列的六条,前三条跟环境有关,后三条跟思路有关。环境问题通常一次就能解决,思路问题会反复出现,遇到时回来对一遍,比到处问人快。
6. 学完第一个例子之后,下一步该往哪走
第一个加法例子跑通,说明环境、编译、事件、界面更新这条链路你已经打通了。接下来最忌讳的是马上扎进复杂项目,然后被一堆没见过的东西劝退。给你一条我自己走过、也带人走过很多遍的路线。
| 阶段 | 花多久 | 具体做什么 | 检验标准 |
|---|---|---|---|
| 控件熟练 | 三到五天 | 把 TWebEdit、TWebComboBox、TWebCheckBox、TWebListBox、TWebMemo 各用一个遍 | 能不看教程做出一个录入表单 |
| 布局过关 | 三到五天 | 用相对定位做一个两栏布局,窗口拉窄不乱 | 在手机浏览器里打开能看 |
| 数据打通 | 一周左右 | 用 REST API 从服务端取一组列表数据,渲染到 TWebListBox | 数据能取到、能显示、加载中有提示 |
| 部署上线 | 一到两天 | 把编译产物传到静态托管,用真实地址访问 | 别人手机能打开你的页面 |
前两个阶段不用碰任何服务端知识,纯控件和布局,最容易建立信心。第三个阶段是分水岭,教程里 REST API 那一部分就是为它准备的,你要开始理解「数据从哪来」这件事。第四个阶段会让你发现一堆只在真实网络环境下才出现的问题,比如缓存、路径大小写、跨域,这些踩一次就记住了。
一个立刻能用的小技巧:每次开始新页面之前,先花五分钟在纸上画出界面上有哪些元素、点了之后各自发生什么,然后再打开 IDE。我早期是直接开 IDE 边想边拖,结果拖到一半发现布局思路不对,全部推倒重来,一晚上就没了。
还有一个习惯值得从第一天就养成:每做完一个小功能,就编译一次、在浏览器里点一遍。别攒着写几百行再跑,那时候报错你根本不知道是哪一行引起的。从那以后我每次改完一段代码都强制走一遍「编译—运行—点一下」的流程,翻车的次数肉眼可见地降下来了。
希望帮到你。
本文还有配套的精品资源,点击获取