Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 久久精品免费看,91视频电影,欧美视频一区二区

          整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          桌面客戶端軟件開發(fā)框架

          桌面客戶端軟件開發(fā)框架

          面客戶端軟件開發(fā)框架是用于創(chuàng)建桌面應(yīng)用程序的工具集合,它們提供了開發(fā)者需要的基本組件、庫和工具,以便于快速構(gòu)建功能豐富、可靠的桌面應(yīng)用程序。以下是一些常用的桌面客戶端軟件開發(fā)框架,希望對大家有所幫助。北京木奇移動技術(shù)有限公司,專業(yè)的軟件外包開發(fā)公司,歡迎交流合作。

          1.Electron:Electron 是一個開源的跨平臺框架,使用 HTML、CSS 和 JavaScript 構(gòu)建桌面應(yīng)用程序。它基于 Chromium 和 Node.js,支持 Windows、macOS 和 Linux 等多個平臺。Electron 由 GitHub 開發(fā),許多知名應(yīng)用如 Slack、Visual Studio Code 和 Discord 都是使用 Electron 構(gòu)建的。

          2.Qt:Qt 是一個跨平臺的 C++ 應(yīng)用程序開發(fā)框架,提供了豐富的 GUI 組件和工具包,可用于構(gòu)建高性能的桌面應(yīng)用程序。Qt 支持 Windows、macOS、Linux 等主流操作系統(tǒng),以及移動平臺如 Android 和 iOS。它被廣泛應(yīng)用于各種行業(yè)領(lǐng)域,包括汽車、航空航天、醫(yī)療等。

          3.JavaFX:JavaFX 是 Java 平臺的圖形界面框架,用于構(gòu)建豐富的交互式桌面應(yīng)用程序。JavaFX 提供了豐富的 UI 控件、動畫效果和多媒體支持,并與 Java 語言緊密集成。JavaFX 可以在 Windows、macOS 和 Linux 等操作系統(tǒng)上運行。

          4.GTK+:GTK+ 是一個跨平臺的 GUI 工具包,使用 C 語言編寫,提供了豐富的界面組件和工具,適用于構(gòu)建 GNOME 桌面環(huán)境下的應(yīng)用程序。GTK+ 支持 Linux、Windows 和 macOS 等操作系統(tǒng)。

          5.WPF (Windows Presentation Foundation):WPF 是 Microsoft .NET Framework 的一部分,用于構(gòu)建 Windows 平臺上的富客戶端應(yīng)用程序。WPF 提供了 XAML 標記語言來定義用戶界面,以及強大的數(shù)據(jù)綁定和樣式化功能。

          6.Cocoa:Cocoa 是 macOS 平臺上的應(yīng)用程序開發(fā)框架,使用 Objective-C 或 Swift 編程語言。它提供了豐富的 API 和工具,用于構(gòu)建 macOS 和 iOS 應(yīng)用程序,并與 macOS 操作系統(tǒng)緊密集成。

          7.Avalonia:Avalonia 是一個跨平臺的 .NET GUI 框架,使用 C# 語言編寫,可用于構(gòu)建 Windows、macOS 和 Linux 上的桌面應(yīng)用程序。Avalonia 的設(shè)計受到 WPF 和 Xamarin.Forms 的啟發(fā),提供了 XAML 標記語言和 MVVM 模式支持。

          選擇桌面客戶端軟件開發(fā)框架時,通常需要考慮開發(fā)者的技能水平、項目需求、目標平臺以及性能要求等因素。

          騎士是哈啰的一款終端安全應(yīng)用,本文主要介紹我們在做新版哈騎士桌面端時的一些技術(shù)架構(gòu)思考和實踐,分享我們沉淀的一些桌面端應(yīng)用的解決方案和經(jīng)驗。

          為什么選擇Electron

          前端開發(fā)者入門快


          Electron是一個使用 JavaScript、HTML 和 CSS 構(gòu)建桌面應(yīng)用程序的框架。嵌入 Chromium 和 Node.js 到 二進制的 Electron 允許您保持一個 JavaScript 代碼代碼庫并創(chuàng)建 在Windows上運行的跨平臺應(yīng)用 macOS和Linux——不需要本地開發(fā)經(jīng)驗,有了它,前端開發(fā)者就可以使用前端開發(fā)技術(shù)來開發(fā)桌面應(yīng)用了。


          支持跨端&開發(fā)效率高


          如上圖所示:

          • Native(C++/C#/Objective-C)不管從原生體驗、包的體積、性能方面來說都是最佳的選擇,但是開發(fā)門檻高、迭代速度慢。
          • QT是基于C++的跨平臺開發(fā)框架,跨平臺應(yīng)用十分廣泛(Mac、Windows、ios、Android、Linux、嵌入式),眾所周知的WPS就是用QT開發(fā)的。性能很好,甚至于可以媲美原生的體驗,但是整體門檻還是比較高的。
          • NW也是一個跨平臺的框架,但是其社區(qū)以及解決方案相對于Electron來說并不是那么強大,而且所有的非javascript編寫的模塊都需要重新用nw-gyp重新編譯,相對于Electron來說,不是那么靈活。
          • Tauri也是一個非常火爆的跨平臺的桌面端框架,相對于Electron來說還不是那么成熟,生態(tài)方面也略顯青澀,兼容性問題有待考證。

          作為一個跨平臺的桌面應(yīng)用開發(fā)框架,Electron 的迷人之處在于,它是建立在 Chromium 和 Node.js 之上的,二位分工明確,一個負責界面,一個負責背后的邏輯。雖然系統(tǒng)間還是會有很大的差異,需要相應(yīng)地做一些額外處理,使得打包出的應(yīng)用在不同系統(tǒng)下都能正常運轉(zhuǎn),但相比于 80% 都能完全復用的代碼,這些時間和成本都是可以忽略的,開發(fā)效率直接翻倍,如果你開發(fā)一個不需要太關(guān)注底層的桌面端應(yīng)用,基本不需要做底層的抹平邏輯。



          另外,Electron 是基于 Node.js 的,這就意味著,Node 這個大生態(tài)下的模塊,Electron 都可以用。同時,跨平臺也讓 Electron 可同時開發(fā) Web 應(yīng)用和桌面應(yīng)用,無論是 UI,還是代碼,很多資源都可以共享,大幅減少了開發(fā)者的工作量。


          生態(tài)繁榮&案例成熟


          Electron生態(tài)的確很強大,各種庫和工具包都為你構(gòu)建一個桌面端應(yīng)用提供了很多方案。



          當然,不止如此,現(xiàn)在用Electron做桌面端的案例也非常成熟了。上圖已經(jīng)說明了Electron應(yīng)用是有多廣泛了,這其中不乏大名鼎鼎、如雷貫耳的應(yīng)用,例如 Postman、Skype、VScode 等。而且我敢打賭,各位看官的電腦上一定安裝過用 Electron 開發(fā)的應(yīng)用,如果你用的是 Mac 電腦,請在命令行運行下面的命令來檢測本地采用 Electron 技術(shù)開發(fā)的桌面軟件:

          for app in /Applications/*; do;[ -d $app/Contents/Frameworks/Electron\ Framework.framework ] && echo $app; done


          Electron生態(tài)開發(fā)技術(shù)選型

          腳手架選型

          關(guān)于腳手架的選擇,其實也很多。


          官方提供的有Electron Forge,Electron Fiddle,electron-quick-start,其實如果你的應(yīng)用不復雜,可以用官方的腳手架生成一個快速上手的模版,然后就可以愉快地開發(fā)了。


          當然也有一些開源的腳手架,比如electron-vue或vue-cli-plugin-electron-builder之類的,也可以讓你快速的生成一個固定的模版,然后往里面填充你的內(nèi)容。


          個人認為,官方的腳手架工具可以用來嘗鮮,學習使用,electron-vue這類工具,如果是在一個企業(yè)級的項目中使用,前期會給你帶來便利,但是后期擴展不會太友好,另外就是他們是基于webpack構(gòu)建的工具,在日常的開發(fā)和使用中會覺得編譯得不夠快(相對于Vite)。


          另外就是如果你想自己完成一個項目腳手架(項目框架),完全可以憑借自己的經(jīng)驗或者參考開源項目的架構(gòu)自己來完成一個腳手架,一來是為了更加了解Electron的構(gòu)建原理,二來是可以搭建出適合自己風格項目的腳手架,后期利于擴展和豐富。


          所以我們腳手架的選型就是自己來造一個Electron的項目架構(gòu),從package.json開始,用Vite+Electron+React構(gòu)建一個Electron項目。


          網(wǎng)絡(luò)模塊選型

          Electron發(fā)送HTTP請求的方案有很多。


          第一種就是渲染進程和主進程分別用相應(yīng)的請求HTTP請求工具來進行網(wǎng)絡(luò)請求,比如渲染進程可以使用fetch,主進程用net模塊。這種方案的優(yōu)點就是可以把渲染進程和主進程的請求分開,分工明確,而且調(diào)試也方便,渲染進程可以直接看network;缺點就是,如果要對請求進行統(tǒng)一封裝的話,比較麻煩。


          第二種就是所有的請求統(tǒng)一封裝,如果你都使用net模塊或者其他的請求工具包對請求進行統(tǒng)一的封裝,然后主進程直接使用,渲染進程調(diào)用統(tǒng)一的橋接方法。這種方案就是完全可以統(tǒng)一請求封裝,但是如果想調(diào)試的請求的話,不方便,需要在主進程來日志信息。


          第三種就是,直接axios直接一把梭,它既支持node環(huán)境,也支持瀏覽器環(huán)境。這種方案非常方便,你就按照之前封裝Web應(yīng)用請求的思路去封裝自己的請求模塊就行,不過需要注意跨域問題。


          對于上面的幾種方案,各有各的優(yōu)缺點,可以根據(jù)自己的場景需求來決定使用哪種方案。我們選擇了axios來設(shè)計網(wǎng)絡(luò)請求模塊。


          本地數(shù)據(jù)庫選型

          Electron的本地數(shù)據(jù)存儲方式也有很多種,可以直接讀寫文件,也可以用相關(guān)的庫,方便數(shù)據(jù)管理。一些庫的對比,詳情:https://www.npmtrends.com/electron-store-vs-lokijs-vs-lowdb-vs-nedb-vs-realm



          綜合來看lowdb更勝一籌,所以選擇lowdb做本地數(shù)據(jù)庫,非常好的一點是它支持同步,不必擔心數(shù)據(jù)沒有寫入就進行了下一步需要本地數(shù)據(jù)的業(yè)務(wù)操作。


          日志工具選型

          日志工具對Electron的開發(fā)也是尤為重要的,可以給你定位到一些表層無法定位的問題,所以一款好的日志工具對開發(fā)是非常有幫助的。


          比較常見的日志工具就是electron-log和log4js-node,這兩款日志工具我都有用過。可以看下npm的排行,這里把express-winston和logging也加上看一下,詳情:https://npmtrends.com/electron-log-vs-express-winston-vs-log4js-vs-logging



          這里簡單說一下electron-log和log4js-node的比較,兩者上手都比較簡單,log4js-node暴露的API 非常多,electron-log就稍顯遜色了,另外最直觀的感受就是,electron-log的日志文件路徑不好找,暫時沒發(fā)現(xiàn)自定義日志路徑的方法,log4js-node有相應(yīng)的方法,而且你可以自定義各種文件類型。


          根據(jù)使用體驗,覺得log4js-node更好,推薦log4js-node。


          構(gòu)建工具選型

          三種構(gòu)建工具electron-builder, electron-forge, electron-packager 對比一下。



          從這個排行來看electron-builder的確很強,electron-forge最近又更新大的版本,不過沒有嘗鮮,我在electron-builder上倒是踩了不少坑,可以分享給大家。所以我在開發(fā)的時候選擇的構(gòu)建打包工具是electron-builder,它把整套解決方案都集成了,包括打包、更新、簽名、分發(fā),基本的鉤子和配置都有相應(yīng)的暴露。


          核心架構(gòu)實現(xiàn)

          架構(gòu)概覽


          我們整個框架是基于Eletcorn + Vite構(gòu)建的,在底層依賴的安全能力和存儲模塊的基礎(chǔ)設(shè)施之上設(shè)計了一層基礎(chǔ)框架,實現(xiàn)構(gòu)建打包,架構(gòu)分層的設(shè)計,然后給整個桌面應(yīng)用提供一些應(yīng)用管理能力和GUI管理相關(guān)的能力,最上層就是為了一些業(yè)務(wù)場景提供的一些應(yīng)用能力,包括核心的幾個應(yīng)用和主要的策略引擎應(yīng)用(終端策略和合規(guī)策略)。


          開發(fā)構(gòu)建

          Electron是多進程架構(gòu)的體系,所以我們在開發(fā)構(gòu)建的時候就是構(gòu)建多個進程來實現(xiàn)我們的應(yīng)用。核心思路是通過Vite構(gòu)建三個進程:渲染進程,任務(wù)進程,主進程,然后最后將三個進程融合起來,就形成了一個應(yīng)用。核心代碼如下:



          幾個注意點:

          • 我們這里利用了writeBundle,就是等chunk都寫入文件后,再啟動Electron進程。
          • 這里沒有利用Electron的命令啟動,而是通過Node.js的child_process模塊的spawn方法啟動Electron子進程,主要是因為我們需要依賴開發(fā)環(huán)境的渲染進程。
          • 另外就是config/vite/main.js中需要對rollupOptions的external進行electron的配置,把導入包轉(zhuǎn)成外部依賴,不然在啟動Electron會找不到Electron的路徑。
          • 在createMainServer中我們注入了全局可使用的變量,以便Electorn加載頁面的時候可以使用這些變量。


          架構(gòu)分層


          因為需要跨端開發(fā),Mac和Windows有些底層模塊的實現(xiàn)還是有不一樣的地方,所以我們在開發(fā)設(shè)計的時候?qū)⒋a進行了分層設(shè)計,這樣至上而下的調(diào)用在上層看來是一樣的,所以我們需要磨平端上底層的差異,現(xiàn)階段我們底層模塊的實現(xiàn)是通過目錄來嚴格區(qū)分的,這樣在開發(fā)一個底層的功能的時候就可以做到各段相互不影響。


          打包升級

          桌面客戶端相當于傳統(tǒng)的Web應(yīng)用在打包和更新這一塊還是有非常大的不同的,傳統(tǒng)的web應(yīng)用幾乎不用所謂的升級,瀏覽器刷新頁面即可,但是桌面客戶端就需要完整的給用戶一個可以立即執(zhí)行的安裝應(yīng)用程序,而且還要可持續(xù)迭代和更新,所以在打包升級這一塊,我們也是踩了不少坑。



          1. 關(guān)于打包

          打包其實Electron的生態(tài)也是非常成熟的,如上面提到的構(gòu)建技術(shù)選型,我們選擇的是electron-builder,它提供了一套打包構(gòu)建升級的流程,暴露了很多API,傻瓜式的配置就基本可以讓你實現(xiàn)一個應(yīng)用的打包了,唯一麻煩的就是簽名和認證應(yīng)用。


          在Windows端我們使用pfx格式的證書進行認證,在進行打包的時候會和證書客戶端軟件交互,完成各個文件的簽名,這樣用戶使用客戶端的時候就是簽名過的軟件了。


          在Mac端我們需要使用蘋果認證的開發(fā)者證書進行簽名和認證,配置相應(yīng)的identity后,構(gòu)建打包的時候會直接跟你本地的證書進行交互,然后對文件進行簽名,當前我們還需要讓應(yīng)用可以不必嚴格使用 MAP_JIT 標識也能寫入和運行內(nèi)存內(nèi)容。所以需要加入entitlements和entitlementsInherit。

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
          <plist version="1.0">
            <dict>
              <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
              <true/>
            </dict>
          </plist>


          到這一步其實Mac端的軟件簽名就完成了,但是如果應(yīng)用想App Store上架的話還需要對應(yīng)用進行公證。公證主要是使用electron-notarize來進行公證,啟用afterSign即可,

          afterSign: './script/notarize.js',


          下面的Apple ID就是你的開發(fā)者賬號,appleIdPassword需要生成一個專用的應(yīng)用密碼,不要使用你本來的Apple ID密碼。

          const { notarize }=require("electron-notarize");
          
          
          exports.default=async function notarizing(context) {
            const { electronPlatformName, appOutDir }=context;
            if (electronPlatformName !=="darwin") {
              return;
            }
          
          
            const appName=context.packager.appInfo.productFilename;
          
          
            console.log(\`公證中...\`)
          
          
            return await notarize({
              appBundleId: "mac.hellobike.knight",
              appPath: \`${appOutDir}/${appName}.app\`,1
              appleId: "XXXXX@outlook.com",
              appleIdPassword: "XXXXX",
            });
          };


          notarize會根據(jù)你的配置去校驗?zāi)愕膽?yīng)用是否可以公證成功,公證的時候會和蘋果的服務(wù)器進行通訊,所以需要保持網(wǎng)絡(luò)不要斷開,成功或者失敗之后都會發(fā)送相應(yīng)的郵件到你的開發(fā)者郵箱里面。


          到這里打包的核心工作就做完了,如果你需要其他個性化配置,參考electron-builder官方的文檔即可。


          2. 關(guān)于升級

          升級我們在Mac和Windows上的實現(xiàn)各有不同,因為相比于傳統(tǒng)的軟件,我們哈騎士會一直保活在用戶的進程中,所以在更新升級的時候也會打破原本Electron升級的機制。


          在Windows上其實還好,可以利用electron-updater本身的生命周期來完成下載,更新,重啟應(yīng)用,因為Windows的保活是用另外的服務(wù)來實現(xiàn)的,所以并不會對整個更新周期產(chǎn)生破壞性的影響。


          但是Mac端的保活實現(xiàn)是打破了electron-updater本身的生命周期的,探究其源碼會發(fā)現(xiàn)Electron自己的升級服務(wù)其實也是一個保活的應(yīng)用服務(wù),所以在升級之前需要將其Kill后才能完成哈騎士自己本身的更新邏輯,另外就是文件占用和鎖定的問題,為此我們自研了一套更新腳本程序結(jié)合electron-updater的下載更新的能力實現(xiàn)了Mac端軟件的升級。


          核心能力沉淀

          基礎(chǔ)能力

          我們在做哈騎士客戶端的時候,也沉淀了一些與業(yè)務(wù)無耦合的組件和工具類,這些組件和工具在桌面端應(yīng)用的場景都比較通用。



          • 本地數(shù)據(jù)庫管理
            本地數(shù)據(jù)存儲是業(yè)務(wù)場景中隨處可見的重要功能。為此,我們封裝了常用的增刪改查數(shù)據(jù)庫的能力,并提供給各個進程使用,以實現(xiàn)數(shù)據(jù)持久化存儲。
          • 底層橋接
            底層橋接是解決Electron和Node無法覆蓋所有應(yīng)用場景的必要手段。我們在橋接層封裝了三種橋接模式,分別為渲染進程調(diào)用的jsBridge能力、主進程調(diào)用dll和dylib插件的能力,以及橋接rust程序的能力。這三種模式基本上可以解決所有技術(shù)瓶頸。
          • 客戶端請求
            客戶端請求模塊也是至關(guān)重要的。我們將其封裝成了通用的http請求庫,支持主進程、渲染進程和任務(wù)進程的調(diào)用,以抹平上層調(diào)用的差異性。
          • 任務(wù)管理
            由于業(yè)務(wù)場景和客戶端的特殊性,我們經(jīng)常需要進行本地任務(wù)管理。因此,我們將任務(wù)管理模塊封裝成了通用的工具類,以支持對任務(wù)的注冊、啟動、停止和銷毀等各項生命周期的管理。


          應(yīng)用能力

          在上面這些基礎(chǔ)能力的組合應(yīng)用下,我們形成了一個強大的策略引擎應(yīng)用。



          該策略引擎應(yīng)用實現(xiàn)了端上任務(wù)調(diào)度和分發(fā)功能。首先接收后臺配置的策略信息,然后生成對應(yīng)的任務(wù),并分發(fā)到各個子任務(wù)中心以執(zhí)行對應(yīng)的策略。最后,將策略執(zhí)行情況報告給服務(wù)端。


          總結(jié)

          Electron在哈騎士的應(yīng)用非常成功,雖然在使用過程中遇到了一些問題,但不可否認它是目前最適合我們業(yè)務(wù)目標和開發(fā)資源的框架。使用Electron使需求交付效率得到了很大的提升。


          我們也將持續(xù)關(guān)注性能和穩(wěn)定性的優(yōu)化、桌面端全鏈路日志的完善以及增量更新升級能力等方面的改進。

          作者:徐濤燾

          來源:微信公眾號:哈啰技術(shù)

          出處:https://mp.weixin.qq.com/s/8v5lyl-yI4AMxQgSwDmkWw

          ebView2 是越來越香了。

          WebView2 不但是 Win11 自帶的系統(tǒng)組件,Win10 也已經(jīng)自動推送安裝。即使是少量沒有安裝 WebView2 的系統(tǒng) —— 使用 aardio 中的 web.view 也會自動安裝( 不需要寫任何代碼 )。

          我用 WebView2 開發(fā)了很多項目,不得不說 WebView2 穩(wěn)定可靠、性能強悍,接口簡潔,是真的讓人省心。

          htmx.js

          這里介紹一個適合用于 WebView2 的極簡前端組件 htmx.js ,這個組件最大的特色就是簡單,一學就會,也很容易理解。

          我們正常瀏覽一個網(wǎng)頁的過程是在瀏覽器里輸入網(wǎng)址,向 HTTP 服務(wù)器發(fā)送請求。然后服務(wù)器返回 HTML 代碼,瀏覽器顯示頁面。

          但是 htmx.js 腦洞大開,讓網(wǎng)頁上的每一個 HTML 節(jié)點都可以向服務(wù)器發(fā)送請求并獲取 HTML,并實時更新頁面上指定的節(jié)點。而且不需要寫任何 JavaScript 代碼。

          起步

          首先我們打開 aardio ,創(chuàng)建 WebView2 工程并選擇 htmx.js 模板:

          生成的工程如下:

          點『運行』可直接測試效果,點『發(fā)布』可生成獨立 EXE 文件 。

          在工程管理器中右鍵點『網(wǎng)頁』彈出菜單,然后點『用外部編輯器打開』,如果安裝了 VS Code 會使用 VS Code 打開網(wǎng)頁目錄。

          在 VS Code 中點擊并打開 index.html 源碼:

          htmx.js 基礎(chǔ)

          打開 index.html ,先看最簡單的 htmx.js 示例:

          <button hx-get="/api/index.aardio" 
              hx-swap="innerHTML" 
              hx-trigger="click" 
              hx-target="#info-div"  >
              點這里發(fā)送 GET 請求
          </button><br>
          
          <div id="info-div"></div>

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

          hx-trigger 用于指定在什么事件發(fā)生時觸發(fā) HTTP 請求,例如:

          hx-trigger="click" 

          表示在 click 單擊事件發(fā)生時觸發(fā)請求。

          hx-trigger 可使用標準網(wǎng)頁事件名,常用事件如下:

          • load - 網(wǎng)頁元素首次加載時觸發(fā)請求
          • click - 單擊時觸發(fā)請求這是除表單,表單控件之外所有元素的默認事件
          • change - 控件值改變時觸發(fā)請求。input,textarea,select 等控件的默認事件
          • submit - 提交表單時觸發(fā)請求。表單的默認事件
          • keydown - 按鍵時觸發(fā)請求
          • keyup - 放開按鍵時觸發(fā)請求
          • mouseenter - 鼠標進入時觸發(fā)請求
          • mouseleave - 鼠標離開時觸發(fā)請求
          • every 時間 - 定時觸發(fā)請求,例如 hx-trgger="every 1s" 指定每隔 1 秒發(fā)送一次請求。

          事件名后面還可以添加修飾器,例如修飾器 once 表示只允許觸發(fā)一次 :

          hx-trigger="click once" 

          其他事件修飾器:

          • changed - 只有在元素的值更改時發(fā)出請求
          • delay:延時 - 在指定的延時后發(fā)出請求,例如 hx-trgger="load delay:1s" 指定元素加載后延遲 1 秒發(fā)送請求。如果服務(wù)端不斷地返回相同 HTML 并替換節(jié)點自身,也可以實現(xiàn)輪詢的效果( aardio 后端可以控制何時停止輪詢 )。
          • throttle:延時 - 節(jié)流,避免在指定時間內(nèi)重復請求
          • from:CSS選擇器 - 監(jiān)聽指定元素上的事件。

          下面的 HTML 使用了多個事件修飾器:

          <input type="text" 
            hx-trigger="keyup changed delay:500ms"
            hx-post="/api/index.aardio" >

          這表示在按鍵放開( keyup ),文本框的內(nèi)容發(fā)生改變( changed )時觸發(fā),并且延時 500 毫秒再發(fā)送請求。

          hx-get 則指定要請求的是哪個后端頁面,例如:

          hx-get="/api/index.aardio" 

          表示事件觸發(fā)時,請求 "/api/index.aardio" 這個頁面。因為 aardio 在啟動 SPA 應(yīng)用時自動指定了后端根目錄為 "/web",所以實際請求的是 "/web/api/aardio" 。

          而 hx-swap 則指定要將返回的 HTML 寫入到哪里,"innerHTML" 指定是更新網(wǎng)頁節(jié)點內(nèi)部 HTML,"outerHTML" 指定替換目標網(wǎng)頁節(jié)點的全部 HTML ,其他還有 "afterbegin" , "beforebegin" , "beforeend" , "afterend" , "none" 。這些看名字就知道是什么作用,就不解釋了。

          hx-target 屬性用 CSS 選擇器指定要寫入的網(wǎng)頁節(jié)點,例如:

           hx-target="#info-div" 

          指定服務(wù)器返回的 HTML 寫入 id 為 "info-div" 的節(jié)點。如果省略 hx-target 屬性表示寫入目標是當前節(jié)點自身。

          hxmx.js 在更新 HTML 時,如果發(fā)現(xiàn)新舊 html 中有 id 相同的元素會進行優(yōu)化并平滑顯示。

          看到這里,htmx.js 您已經(jīng)會用了。

          雖然 htmx.js 文檔里有更多花式用法,但一般可能用不上。有些事搞太復雜了也不一定是好事。

          htmx.js + aardio 后端

          aardio 提供了嵌入式 HTTP 服務(wù)器,可以直接使用 aardio 代碼寫網(wǎng)頁,支持與 PHP 類似的模板語法。

          aardio 的模板語法很簡單,aardio 代碼寫在 <? ?> 內(nèi)部,而 HTML 代碼寫在 <? ?> 外部就可以了。實際上 <? ?>外部的代碼被轉(zhuǎn)換為了 aardio 中 print 函數(shù)的參數(shù)。

          例如服務(wù)端有下面的 aardio 代碼:

          <span>abc</span>
          <?
            response.write("123")
          ?>

          運行后會自動轉(zhuǎn)換為純 aardio 代碼如下:

          print("<span>abc</span>");
          response.write("123");

          在 HTTP 后端中,print 函數(shù)實際上就是指向用于向 HTTP 客戶端輸出數(shù)據(jù)的 response.write() 函數(shù)。

          在 HTTP 后端有兩個最常用的對象,request 對象包含了所有 HTTP 請求信息,而 response 對象為 HTTP 響應(yīng)對象,用于向客戶端發(fā)送數(shù)據(jù)。

          打開 aardio 自帶「工具 > 庫函數(shù)文檔」,點擊 fastcgi.client 的文檔可以查看 request, response 對象的所有屬性與方法。aardio 中的所有 HTTP 服務(wù)端實現(xiàn)都統(tǒng)一兼容 fastcgi.client 文檔規(guī)定的 request, response 用法。

          也可以參考 aardio 開始頁的 《 aardio 網(wǎng)站開發(fā)、FastCGI開發(fā)入門教程 》。至于 aardio 模板語法,請參考 《 aardio 語法與使用手冊 > aardio 語言 > 模板語法 》

          aardio 的模板語法不僅僅可以用于寫 HTTP 后端,也不僅僅是可以用于輸出 HTML,實際上可以用于生成任何字符串。aardio 中的很多功能都支持這種模板語法,例如運行時編譯 C# 代碼就支持用 aardio 模板語法生成 C# 代碼。另外 aardio 提供 string.loadcode() 函數(shù)可以直接解析 aardio 模板并返回字符串。

          htmx.js指示動畫,aardio 后端線程

          這里要注意,上面范例工程默認導入的 HTTP 服務(wù)器是:

          wsock.tcp.simpleHttpServer;

          這是一個多線程的 HTTP 服務(wù)端,每次被請求執(zhí)行的 aardio 代碼都是在后臺線程中運行。aardio 多線程開發(fā)要注意的是每個線程都運行在獨立的環(huán)境,全局變量是相互隔離的,這個限制實際上讓 aardio 的多線程開發(fā)更簡潔,坑更少,具體請參考 aardio 自帶「范例程序 > aardio 語言 > 多線程」。

          如果改為 wsock.tcp.asynHttpServer 則是單線程異步的 HTTP 服務(wù)器。

          下面我們?nèi)匀皇褂媚J的 simpleHttpServer 。多線程的好處是耗時操作不會卡界面。后端在進行耗時操作時,網(wǎng)頁前端通常需要顯示一個動畫,htmx.js 做這事就很簡單。

          我們只要簡單的修改一下前面講過的網(wǎng)頁代碼如下:

          <button hx-get="/api/index.aardio" 
              hx-indicator="#indicator" >
              點這里發(fā)送 GET 請求
          </button><br>
          
          <img id="indicator" 
              class="htmx-indicator" 
              src="/images/loading.gif"/>

          主要是增加了 hx-indicator 屬性,該屬性的值用一個 CSS 選擇器指定了發(fā)送 HTTP 請求時要顯示的 HTML 元素,這里指定的是 id 為 "indicator" 的元素。

          實際上我們可以自定義這個請求動畫的樣式,我們打開樣式文件 index.css 添加下面的樣式:

          .htmx-indicator{
              display:none;
          }
          .htmx-request.htmx-indicator{
              display:inline;
          }

          在發(fā)送請求時,網(wǎng)頁上被設(shè)定的指示元素會自動添加 CSS 類 "htmx-request",HTTP 請求結(jié)束會移除該類。

          然后我們打開對應(yīng)的 aardio 后端代碼 /web/api/index.aardio ,輸入以下代碼:

          <span>
          <?
          
          if( request.method=="GET"){
              
              /*
              這是多線程后端,
              這里等 2 秒,網(wǎng)頁會顯示加載動畫
              */
              sleep(2000);
              
              response.write( time() )    
          } 
          ?></span>


          上面的代碼的作用是:如果收到 GET 請求,線程就休眠 2 秒以模擬耗時操作。然后輸出當前時間。

          我們運行一下看看效果:

          請求參數(shù)

          htmx.js 提交請求的節(jié)點如果是一個表單控件,只要指定 name 屬性 —— 就會自動以該名字發(fā)送請求參數(shù),參數(shù)值就是控件的值。

          如果提交請求的節(jié)點是表單,則 HTTP 請求參數(shù)為表單內(nèi)所有控件的值。

          也可以在節(jié)點的 hx-vals 屬性中用一個 JSON 對象指定請求參數(shù),例如網(wǎng)頁這樣寫:

          <button hx-get="/api/index.aardio" 
              hx-vals='{"myVal": "值"}'>
              點這里發(fā)送 GET 請求
          </button><br>

          aardio 后端就可以使用:

          request.get["myval"]

          取到 HTTP 請求參數(shù) myval 的值。

          如果使用 POST 發(fā)送請求,例如:

          <button hx-post="/api/index.aardio" 
              hx-vals='{"myVal": "值"}'>
              點這里發(fā)送 GET 請求
          </button><br>

          那么 aardio 后端可以使用

          request.post["myval"]

          取到 HTTP 請求參數(shù) myval 的值。

          在 aardio 后端使用:

          request.query("myval")

          可以取到 GET 或 POST 發(fā)送的 myval 參數(shù)值。

          hx-vals 還可以通過加上 javascript: 或者 js: 前綴后使用 JS 對象返回請求參數(shù),例如:

          <button hx-get="/api/index.aardio"  
              hx-vals='javascript:{myVal: "值"}'    >
              點這里發(fā)送 GET 請求
          </button> 

          web.form 也玩 htmx.js

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

          web.form 是基于系統(tǒng)自帶的 IE 內(nèi)核控件,注意系統(tǒng)雖然刪除了 IE 瀏覽器,但 IE 控件屬于系統(tǒng)組件,Windows 有說明該控件不會被移除。IE 控件的好處是從 XP 到 Win11 所有操作系統(tǒng)都自帶。

          而且 IE 控件很輕量,與本地程序交互的接口也非常方便。Win10 ,Win11 自帶的是 IE11 內(nèi)核,寫寫一般的網(wǎng)頁還是很好用的。至于 Win7 —— 因為只有極低的份額,一般軟件不用考慮。

          htmx.js 最后一個支持 IE 11 的版本是 1.6.1 ,這個足夠用了。前面說過我們需要的只是局部請求刷新的功能,其他功能我們用不上,所以追新無意義。

          首先我們打開 aardio 工程向?qū)Вx擇「 Web 界面 > Web Form 」然后創(chuàng)建工程即可,新版工程模板默認就是使用 htmx.js 。

          其他 HTML 代碼寫法與前面介紹的 WebView2 基本一樣。不過 web.form 本就支持 EXE 內(nèi)嵌資源文件,所以默認并不會啟動 HTTP 服務(wù)器,需要多寫幾句代碼。

          打開工程的 webPage.aardio 源碼:

          可以看到源碼中是如下啟動 HTTP 服務(wù)器的:

          import web.form;
          var wb=web.form(winform); 
          
          //多線程后端
          import wsock.tcp.simpleHttpServer;
          wsock.tcp.simpleHttpServer.documentBase="\web"
          var indexUrl=wsock.tcp.simpleHttpServer.startUrl("\index.html")
           
          wb.go(indexUrl);

          我并沒有把這幾句代碼封裝到 wb.go() 函數(shù)中。

          有些新手總以為代碼越少越好,其實并非如此,有時候多寫幾句更容易看清楚代碼的思路,更容易理解我們正在使用的技術(shù)。

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

          上面示例程序的主窗口是使用 win.ui.tabs 做的,只有其中一個標簽頁用到了網(wǎng)頁。

          其實一般桌面軟件的界面并不是一定要全部使用網(wǎng)頁實現(xiàn)。有時候我們將界面中適合用網(wǎng)頁呈現(xiàn)的部分用網(wǎng)頁做,可能會更好。

          我們在使用任何技術(shù)時,都要考慮一下適不適合。沒有一樣技術(shù)能適合做所有的事,多個選擇總是好事。


          主站蜘蛛池模板: 日韩免费观看一区| 亚洲AV美女一区二区三区| 久久国产精品最新一区| 又紧又大又爽精品一区二区| 国产福利一区二区| 夜夜添无码一区二区三区| 日韩一区二区视频| 日韩AV在线不卡一区二区三区| 国产一区麻豆剧传媒果冻精品| 亚洲香蕉久久一区二区三区四区 | 一区二区三区美女视频| 亚洲国产成人一区二区精品区| 日韩精品一区二区三区毛片| 日韩电影一区二区三区| 福利一区二区视频| 中文字幕无线码一区2020青青| 精品无码综合一区| 国产精品一区二区AV麻豆| 亚洲一区二区三区首页| 冲田杏梨高清无一区二区| 亚洲综合一区国产精品| 国产在线aaa片一区二区99| 精品视频午夜一区二区| 男人的天堂av亚洲一区2区| 日韩精品无码一区二区三区| 亲子乱AV视频一区二区| 无码精品久久一区二区三区| 精产国品一区二区三产区| 亚洲一区二区三区无码国产| 国产一区二区三区在线看| av在线亚洲欧洲日产一区二区| 怡红院一区二区在线观看| 乱码精品一区二区三区| 亚洲一区免费视频| 欧亚精品一区三区免费| 国产日韩精品一区二区三区| 福利片免费一区二区三区| 成人精品视频一区二区三区| 国产一区二区在线视频| 日韩一区二区在线观看视频| 中文字幕AV无码一区二区三区|