分享

强大 WebView2 + 不用写 JavaScript 的 htmx.js 「小轻快」开发桌面程序

 风声之家 2022-10-28 发布于江苏

WebView2 是越来越香了。

WebView2 不但是 Win11 自带的系统组件,Win10 也已经自动推送安装。即使是少量没有安装 WebView2 的系统 —— 使用 aardio 中的 web.view 也会自动安装( 不需要写任何代码 )。

我用 WebView2  开发了很多项目,不得不说 WebView2  稳定可靠、性能强悍,接口简洁,是真的让人省心。

▶ htmx.js 

这里介绍一个适合用于 WebView2 的极简前端组件 htmx.js ,这个组件最大的特色就是简单,一学就会,也很容易理解。

我们正常浏览一个网页的过程是在浏览器里输入网址,向 HTTP 服务器发送请求。然后服务器返回 HTML 代码,浏览器显示页面。

但是 htmx.js 脑洞大开,让网页上的每一个 HTML 节点都可以向服务器发送请求并获取 HTML,并实时更新页面上指定的节点。而且不需要写任何 JavaScript 代码。

▶ 起步

首先我们打开 aardio ,创建 WebView2 工程并选择  htmx.js 模板:

生成的工程如下:

点『运行』可直接测试效果,点『发布』可生成独立 EXE 文件 。

在工程管理器中右键点『网页』弹出菜单,然后点『用外部编辑器打开』,如果安装了 VS Code 会使用 VS Code 打开网页目录。

在 VS Code 中点击并打开 index.html 源码:


▶ 
htmx.js 基础

打开 index.html ,先看最简单的 htmx.js 示例:










注意看凡是 "hx-" 前缀的属性都是用于 htmx.js 。

hx-trigger 用于指定在什么事件发生时触发 HTTP 请求,例如:



表示在 click 单击事件发生时触发请求。这里使用的是标准的事件名,例如按键 keydown ,放开按键 keyup,鼠标进入 mouseenter 鼠标离开 mouseleave 等等。

而事件名后还可以指定修饰符,例如只允许触发一次的 once :



其他修饰器:






下面的 HTML 使用了多个事件修饰器:





这表示在按键放开( keyup ),文本框的内容发生改变( changed )时触发,并且延时 500 毫秒再发送请求。

hx-get 则指定要请求的是哪个后端页面,例如:



表示事件触发时,请求 "/api/index.aardio" 这个页面。因为 aardio 在启动 SPA 应用时自动指定了后端根目录为 "/web",所以实际请求的是 "/web/api/aardio" 。

而 hx-swap 则指定要将返回的 HTML 写入到哪里,"innerHTML" 指定是更新网页节点内部 HTML,"outerHTML" 指定替换目标网页节点的全部 HTML ,其他还有 "afterbegin" , "beforebegin" , "beforeend" , "afterend" , "none" 。这些看名字就知道是什么作用,就不解释了。

 hx-target  属性用 CSS 选择器指定要写入的网页节点,例如:



指定服务器返回的 HTML 写入 id 为 "info-div" 的节点。如果省略 hx-target 属性表示写入目标是当前节点自身。

hxmx.js 在更新 HTML 时,如果发现新旧 html 中有 id 相同的元素会进行优化并平滑显示。

看到这里,htmx.js 您已经会用了。

虽然 htmx.js 文档里有更多花式用法,但一般可能用不上。有些事搞太复杂了也不一定是好事。

▶ htmx.js + aardio 后端

aardio 提供了嵌入式 HTTP 服务器,可以直接使用 aardio 代码写网页,支持与 PHP 类似的模板语法。

aardio 的模板语法很简单,aardio 代码写在 <? ?> 内部,而 HTML 代码写在 <? ?> 外部就可以了。实际上 <? ?>外部的代码被转换为了 aardio 中 print 函数的参数。

例如服务端有下面的 aardio 代码:






运行后会自动转换为纯 aardio  代码如下:




在 HTTP 后端中,print 函数实际上就是指向用于向 HTTP 客户端输出数据的 response.write() 函数。

在 HTTP 后端有两个最常用的对象,request 对象包含了所有 HTTP  请求信息,而 response 对象为 HTTP 响应对象,用于向客户端发送数据。

打开 aardio 自带「工具 > 库函数文档」,点击 fastcgi.client 的文档可以查看 request, response 对象的所有属性与方法。aardio 中的所有 HTTP 服务端实现都统一兼容 fastcgi.client 文档规定的 request, response 用法。

也可以参考 aardio 开始页的 《 aardio 网站开发、FastCGI开发入门教程 》。至于 aardio 模板语法,请参考 《 aardio 语法与使用手册 > aardio 语言 > 模板语法 》 

aardio 的模板语法不仅仅可以用于写 HTTP 后端,也不仅仅是可以用于输出 HTML,实际上可以用于生成任何字符串。aardio 中的很多功能都支持这种模板语法,例如运行时编译 C# 代码就支持用 aardio 模板语法生成 C# 代码。另外 aardio 提供 string.loadcode() 函数可以直接解析 aardio 模板并返回字符串。

▶ htmx.js 指示动画,aardio 后端线程

这里要注意,上面范例工程默认导入的 HTTP 服务器是:



这是一个多线程的 HTTP 服务端,每次被请求执行的 aardio 代码都是在后台线程中运行。aardio 多线程开发要注意的是每个线程都运行在独立的环境,全局变量是相互隔离的,这个限制实际上让 aardio 的多线程开发更简洁,坑更少,具体请参考 aardio  自带「范例程序 > aardio 语言 > 多线程」。

如果改为 wsock.tcp.asynHttpServer 则是单线程异步的 HTTP 服务器。

下面我们仍然使用默认的 simpleHttpServer 。多线程的好处是耗时操作不会卡界面。后端在进行耗时操作时,网页前端通常需要显示一个动画,htmx.js 做这事就很简单。

我们只要简单的修改一下前面讲过的网页代码如下:










主要是增加了 hx-indicator 属性,该属性的值用一个 CSS 选择器指定了发送 HTTP 请求时要显示的 HTML 元素,这里指定的是 id 为 "indicator" 的元素。

实际上我们可以自定义这个请求动画的样式,我们打开样式文件 index.css 添加下面的样式:








在发送请求时,网页上被设定的指示元素会自动添加 CSS 类 "htmx-request",HTTP 请求结束会移除该类。

然后我们打开对应的 aardio 后端代码 /web/api/index.aardio ,输入以下代码:














上面的代码的作用是:如果收到 GET 请求,线程就休眠 2 秒以模拟耗时操作。然后输出当前时间。

我们运行一下看看效果:

▶ 请求参数


htmx.js 提交请求的节点如果是一个表单控件,只要指定 name 属性 —— 就会自动以该名字发送请求参数,参数值就是控件的值。

如果提交请求的节点是表单,则 HTTP 请求参数为表单内所有控件的值。

也可以在节点的 hx-vals 属性中用一个 JSON 对象指定请求参数,例如网页这样写:






aardio 后端就可以使用:



取到 HTTP 请求参数 myval 的值。

如果使用 POST 发送请求,例如:






那么 aardio 后端可以使用



取到 HTTP 请求参数 myval 的值。


在 aardio 后端使用:



可以取到  GET 或 POST 发送的 myval 参数值。

hx-vals 还可以通过加上 javascript: 或者 js: 前缀后使用 JS 对象返回请求参数,例如:







▶ 
web.form 也玩 htmx.js 

有趣的是 web.form 也可以支持 htmx.js 。

web.form 是基于系统自带的 IE 内核控件,注意系统虽然删除了 IE 浏览器,但 IE 控件属于系统组件,Windows 有说明该控件不会被移除。IE 控件的好处是从 XP 到 Win11 所有操作系统都自带。

而且 IE 控件很轻量,与本地程序交互的接口也非常方便。Win10 ,Win11 自带的是 IE11 内核,写写一般的网页还是很好用的。至于 Win7 —— 因为只有极低的份额,一般软件不用考虑。

htmx.js 最后一个支持 IE 11 的版本是 1.6.1 ,这个足够用了。前面说过我们需要的只是局部请求刷新的功能,其他功能我们用不上,所以追新无意义。

首先我们打开 aardio 工程向导,选择「 Web 界面 > Web Form 」然后创建工程即可,新版工程模板默认就是使用 htmx.js 。

其他 HTML 代码写法与前面介绍的 WebView2 基本一样。不过 web.form 本就支持 EXE 内嵌资源文件,所以默认并不会启动 HTTP 服务器,需要多写几句代码。

打开工程的 webPage.aardio 源码:

可以看到源码中是如下启动 HTTP 服务器的:











我并没有把这几句代码封装到 wb.go() 函数中。

有些新手总以为代码越少越好,其实并非如此,有时候多写几句更容易看清楚代码的思路,更容易理解我们正在使用的技术。

下面我们看下 web.form + htmx.js 范例的运行效果:

上面示例程序的主窗口是使用 win.ui.tabs 做的,只有其中一个标签页用到了网页。

其实一般桌面软件的界面并不是一定要全部使用网页实现。有时候我们将界面中适合用网页呈现的部分用网页做,可能会更好。

我们在使用任何技术时,都要考虑一下适不适合。没有一样技术能适合做所有的事,多个选择总是好事

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多