整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          放棄 Electron,擁抱 WebView2!Ja

          放棄 Electron,擁抱 WebView2!JavaScript 快速開發獨立 EXE 程序

          lectron 不錯,但也不是完美的。
          Electron 帶來了很多優秀的桌面軟件,但并不一定總是適合我們的需求。

          多個選擇總是好事!

          我使用 Electron 遇到的一些麻煩

          1、Electron 太大了!

          2、每一個 Electron 寫的軟件都要重復地帶一個 Electron …… 升級與分發都不方便。

          3、Electron 不方便嵌入其他窗口界面,與其他語言、技術融合不易。

          4、并不是所有桌面軟件都需要 Electron 的跨平臺特性。macOS , Linux 的桌面系統市場份額小于被遺忘的 Windows 8 ,如果軟件只是在 Windows 平臺運行,并且需要大量與專用系統 API 交互,跨平臺反而是不必要的負擔。

          5、我曾經在 aardio 中封裝了一個 electron 擴展庫,然后我在寫這個擴展庫的時候,當時看到的還是 remote 真香 …… 然后我為這個擴展庫寫了個很大的 JS 文件就用到了 remote。可是等我寫完沒多久, 就看到 remote 被 Electron 拋棄了,remote 會慢一萬倍 ,各種缺陷 ……

          WebView2 的優勢

          1、WebView2 基于性能強悍的 Edge(Chromium) 內核。

          2、調用 WebView2 生成的軟件體積很小。所有基于 WebView2 的軟件可以共享同一個 WebView2 組件。Win11 已經內置 WebView2 組件,其他操作系統也可以快速地自動安裝 WebView2 。

          3、WebView2 接口非常簡潔,嵌入其他窗口界面也非常方便。

          總結一句話就是:WebView2 簡單、好用、生成軟件體積小。

          aardio 標準庫中的 web.view 就是基于 WebView2。WebView2 的接口是如此簡潔,所以我寫的這個庫也只有很少的代碼。因為 aardio 可以將網頁自動內嵌到獨立 EXE 文件,就可以非常方便地生成獨立 EXE 程序。

          一個最簡單的程序演示

          下面我們用 aardio 調用 web.view (WebView2)寫一個最簡單的程序:

          import win.ui;
          /*DSG{{*/
          mainForm=win.form(text="WebView2")
          mainForm.add(
          btnCallJs={cls="button";text="調用 JS 函數";left=461;top=395;right=726;bottom=449;note="點這里調用 JavaScript  函數";z=1};
          custom={cls="custom";left=17;top=21;right=730;bottom=356;z=2}
          )
          /*}}*/
          
          //創建瀏覽器組件
          import web.view;
          var wb=web.view(mainForm.custom);
          
          //導出本地函數給網頁 JavaScript
          wb.external={
          	getComputerName=function(){
          		return sys.getComputerName();
          	}
          }
          import sys;
          
          //寫入網頁 HTML
          wb.html=/**
          <html>
          <head>
              <script> 
              (async ()=>{ 
              	var n=await aardio.getComputerName();
              	alert(n);
              })()
              </script>
          </head>
          <body>
          **/
          
          //響應按鈕事件
          mainForm.btnCallJs.oncommand=function(id,event){
          	//調用 JS 函數
          	wb.xcall("document.write","測試")
          }
          
          mainForm.show();
          win.loopMessage();

          對,這就是一個完整程序的源代碼,可以一鍵生成獨立 EXE 文件。

          入門

          首先點選 「aardio 主菜單 > 新建工程 > 窗口程序 > 空白工程」,然后點擊「創建工程」。

          如果熟悉網頁前端開發,也可以點擊 「 新建工程 > Web 界面 > WebView2 」創建工程。

          雙擊工程入口代碼 main.aardio 打開主窗口,自「界面控件」中拖一個 「調用 JS 函數」的按鈕上去,再拖一個 custom 控件到窗體上 —— 用來嵌入網頁

          然后切換到代碼視圖,添加以下代碼創建網頁瀏覽器:

          import web.view;
          var wb=web.view(mainForm.custom);

          web.view 的第 1 個參數指定要嵌入 WebView2 的窗口對象,該參數可以是 mainForm.custom 這樣的控件窗口,也可以是 mainForm 這樣的窗體對象。

          下面使用

          wb.html="<html></html>"

          就可以寫網頁 HTML 代碼了。

          或者使用

          wb.go("網址")

          可以打開指定的網頁。

          使用

          import wsock.tcp.simpleHttpServer;
          wb.go("\res\index.html");

          可以打開資源目錄的網頁,支持SPA 單頁應用。資源目錄可以嵌入 EXE 生成 獨立 EXE 文件,放心不用多寫其他代碼。

          添加下面的代碼導出 external 對象給網頁 JavaScript :

          //導出本地函數給網頁 JavaScript
          wb.external={
          	getComputerName=function(){
          		return sys.getComputerName();
          	}
          }
          
          import sys;

          在網頁 JavaScript 里可以調用上面導出的 external 對象,不過在 JavaScript 里要用 aardio 這個名字表示 external 對象,網頁代碼如下:

          wb.html=/**
          <html>
          <head>
              <script> 
              (async ()=>{ 
              	var n=await aardio.getComputerName();
              	alert(n);
              })()
              </script>
          </head>
          <body>
          **/

          注意在 aardio 中 /* 注釋 */ 可以作為字符串賦值給其他變量,請參考:aardio 編程語言快速入門——語法速覽

          要注意所有 aardio 對象在 JavaScript 中都是異步 Promise 對象。如上在 async 函數體內可以愉快地使用 await 調用 aardio 函數 —— 這非常方便。

          我們在窗體設計視圖雙擊「調用 JS 函數」按鈕,這會切換到代碼視圖,并自動添加以下回調函數:

          mainForm.btnCallJs.oncommand=function(id,event){
          	
          }

          用戶點擊按鈕時就會調用上面的函數。

          小改一下添加 aardio 代碼調用 JavaScript 函數:

          //響應按鈕事件
          mainForm.btnCallJs.oncommand=function(id,event){
          	//調用 JS 函數
          	wb.xcall("document.write","測試")
          }

          很簡單,一個程序就寫好了。可以在 aardio 中點擊「運行」按鈕直接運行代碼,也可以點擊「發布」按鈕直接生成 EXE 文件。

          如何將網頁顯示在窗體的指定位置?并且支持自動縮放?

          web.view() 構造函數的第 1 個嵌入窗口參數可以是 win.form 對象(獨立窗口),也可以是 custom, static 這樣的普通控件對象。例如前面的例子就是將 WebView2 嵌入 custom 控件:

          import web.view;
          var wb=web.view(mainForm.custom);

          aardio 中的所有控件都可以非常方便的支持自動縮放。只要簡單地在窗體設計器中選定控件,然后在「屬性」面板設置「固定邊距」、「自適應大小」這些屬性就可以。

          一個更簡單的方法是在窗體設計器上點右鍵,然后在彈出菜單中點擊「九宮格縮放布局」—— aardio 將會自動設置所有控件的自適應縮放屬性。

          至于網頁內容自適應排版很簡單,不需要在 aardio 中編寫代碼。

          使用 wb.export 導出 aardio 函數到 Javascript

          前面我們介紹過使用 external 導出 aardio 函數到網頁 JavaScript 。我們還可以用 wb.export 導出 aardio 函數,先看例子:

          import web.view;
          var wb=web.view(mainForm.custom);
          
          wb.export({
          	alert=function(msg){
          		winform.msgbox(msg) 
          	};
          	nativeAdd=function(a,b){ 
          		return a + b; 
          	}
          })

          注意:

          1、wb.export() 導出的是 JavaScript 全局函數。

          2、wb.export() 導出的函數在 JavaScript 中同樣是異步 Promise 對象。

          3、wb.export() 導出的 Javascript 全局函數, 使用 JSON 自動轉換調用參數和返回值,可以更好的兼容只能支持純 aardio 對象 / 純 JavaScript 對象的代碼。

          4、wb.export() 導出的函數內部禁止調用 wb.doScript 或 wb.eval 執行Javascript 。

          wb.external 內部是調用 wb.exportHostObject() 導出 aardio 對象,中間不需要經過 JSON 自動轉換。

          示例:網頁 JavaScript 調用本地 Ping 命令

          我經常被問到幾個類似的問題:

          1、JavaScript 的異步函數太麻煩了,怎樣把他搞成同步的,不用 await ,不用 async 。

          2、JavaScript 的異步函數太好用了,怎樣在 aardio 中也這樣搞,如何在 aardio 里 await 。

          其實同步有同步的優勢,異步有異步的好處,揚長避短是智慧,倒行逆施最累人。下面我們一起來寫一個在 WebView2 中調用本地 Ping 命令的小程序體驗一下。


          第一步:創建窗口。

          import win.ui;
          var winform=win.form(text="Ping")

          第二步:基于窗口創建 WebView2 瀏覽器組件。

          import web.view;
          var wb=web.view(winform);

          第三步:使用 external 對象導出 JavaScript 可以調用的本地函數。

          import process.popen;
          wb.external={
            ping=function(domain){
              
              var prcs=process.popen("ping "+ domain);
              for( all,out,err in prcs.each() ){
                  wb.invoke("document.body.insertAdjacentText",'beforeend',all); 
              }
              
              return "恭喜,事做好了!"
            } 
          }

          在 JavaScript 里用 aardio.ping() 就可以直接調用上面的 external.ping() 函數了。

          第四步:下面在網頁里寫 JavaScript 來調用 aardio 函數。

          wb.html=/**
          <body style="white-space: pre;"><script>
          doSomething=async()=> {
              var result=await aardio.ping('www.baidu.com');
              document.body.insertAdjacentText('beforeend',result);
          };
          </script>
          <button  onclick="doSomething()">開始干活了</ping>
          **/

          就這么短短幾句,一個簡單的程序就完成了,請看運行效果:

          上面程序的完整 aardio 源代碼如下:

          //創建窗口
          import win.ui;
          var winform=win.form(text="Ping")
          
          //嵌入瀏覽器組件
          import web.view;
          var wb=web.view(winform);
          
          //導出 aardio 函數到 JavaScript
          wb.external={
          	ping=function(domain){
          		
          		//同步有同步的優勢,揚長避短是智慧,倒行逆施最累人。 
          		var prcs=process.popen("ping "+ domain);
          		for( all,out,err in prcs.each() ){
          		    wb.invoke("document.body.insertAdjacentText",'beforeend',all); 
          		}
          		
          		return "恭喜,事做好了!"
          	} 
          }
          import process.popen;
          
          //寫入網頁 HTML
          wb.html=/**
          <body style="white-space: pre;"><script>
          doSomething=async()=> {
          	
          	//異步有異步的好處,揚長避短是智慧,倒行逆施最累人。
            	var result=await aardio.ping('www.baidu.com');
            	document.body.insertAdjacentText('beforeend',result);
          };
          </script>
          <button  onclick="doSomething()">開始干活了</ping>
          **/
          
          //顯示窗口
          winform.show();
          
          //啟動界面消息循環
          win.loopMessage();

          aardio 調用 JS 函數

          在 aardio 中可以使用 wb.doScript() , wb.eval() , wb.xcall() 等函數調用網頁 JavaScript ,下面看一個在 aardio 中調用 xterm.js 的簡單例子:

          import win.ui;
          var winform=win.form(text="xterm")
          
          import web.view;
          var wb=web.view(winform);
          
          wb.html=/**
          <!DOCTYPE html> 
          <head>
            <meta charset="UTF-8">
            <title></title>
            <link rel="stylesheet" href="https://unpkg.com/xterm@4.13.0/css/xterm.css">
            <script src="https://unpkg.com/xterm@4.13.0/lib/xterm.js"></script>
          </head>
          <body style="height:100vh;"> 
            <script>
              let term=new Terminal();
              term.open(document.body);
              term.write('\x1b[31m紅色字體\x1b[37m測試')
            </script>
          </body>
          </html>
          **/
          
          wb.xcall("term.write",'\e[32m綠色字體');
          
          winform.show();
          win.loopMessage();

          無邊框窗口:用網頁實現窗口標題欄

          「無邊框窗口」指的是去掉獨立窗體默認的邊框與標題欄,然后由程序自行定制邊框與標題欄。

          aardio 做這事還是很容易的,首頁在窗體屬性中指定「邊框」屬性為 none。

          這樣直接運行后顯示的窗體就沒有邊框和標題欄了( 按 Alt + F4 關閉窗口 )。

          然后添加下面的代碼就可以為窗體添加標題欄、標題欄按鈕、陰影邊框、并支持拖動邊框縮放:

          import win.ui.simpleWindow;
          win.ui.simpleWindow(winform);

          win.ui.simpleWindow 的源碼很簡單,參考其源碼也可以自己編寫新的庫定制邊框與標題欄。

          這里我們不用上面的方法,而是用網頁實現標題欄。

          我們知道網頁繪制一個標題欄與標題欄按鈕很簡單,難點在于怎么在網頁里控制窗口。我們先學習幾個專用于無邊框窗口的 aardio 函數:

          winform.hitMax() //模擬點擊最大化按鈕
          winform.hitMin() //模擬點擊最小化按鈕
          winform.hitClose() //模擬點擊關閉按鈕
          winform.hitCaption() //拖動標題欄

          下面寫個簡單的例子,先看下運行效果:

          WebView2 無邊框窗口示例完整源碼如下:

          import win.ui;
          /*DSG{{*/
          var winform=win.form(text="無邊框窗口";right=759;bottom=469;bgcolor=16777215;border="none")
          winform.add()
          /*}}*/
          
          import web.view;
          var wb=web.view(winform);
           
          //導出為 Javascript 中的 aardio 對象
          wb.external={ 
          	close=function(){
          		winform.close();
          	};
          	hitCaption=function(){
          		winform.hitCaption();
          	};
          	hitMin=function(){
          		winform.hitMin();
          	};
          	hitMax=function(){
          		return winform.hitMax();
          	};
          }
          
          wb.html=/**
          <!doctype html>
          <html>
          <head>
              <meta charset="utf-8">
          	<style type="text/css">
          	html {
              	margin: 0px;
              	padding: 0px; 
          		background-color: #202020; 
          	}
          	
          	#title-bar {
          		height: 32px;	
          		padding: 0px;
              	margin: 0px;
          	}
          	
          	#title-bar .caption {
          		position: fixed;
          		top: 0px;
          		left: 0px;	
          		width: 100%;
          		padding-left: 10px;
          		color: #ADADAD;
          		line-height: 32px;
          		font-size: 14px;
          		cursor: default;
          		user-select:none;
          	}
          	
          	#title-bar .buttons {
          		position: fixed;
          		top: 1px;
          		right: 1px;	
          	}
          	
          	#title-bar button {
          		font: 14px Marlett ;
          		color: #F5F5F5;
          		background-color: transparent;
          		border: none;
          		height: 28px;
          		width: 28px;  
          	}
          	 
          	#title-bar button:hover {
          		background-color: #FF4500;
          	}
          	
          	#title-bar button:active {
          		background-color: #B0451E;
          		color: #C5C5C5;
          	}
          	
          	#main {
          		padding: 12px;	
          		color: #C0C0C0;
          	}
          	 
              </style>
              <script type="text/javascript">  
              
              </script>
          </head>
            <body>
              <div id="title-bar" >
                <div class="caption" onmousedown="aardio.hitCaption()">按住這里調用 aardio.hitCaption() 拖動窗口 </div>
                <div class="buttons">
                  <button id="min-btn" onclick="aardio.hitMin()">0</button>
                  <button id="max-btn"  onclick="aardio.hitMax()">1</button>
                  <button id="close-btn" onclick="aardio.close()">r</button>
                </div>
              </div>
              <div id="main">
            	  1、請指定窗體「邊框」屬性為 none ,創建無邊框窗口。<br />
            	  2、調用 win.ui.shadow(winform) 創建陰影邊框<br />
              </div>
              <script src="default.js"></script>
            </body>
          </html>
          **/ 
          
          //添加陰影邊框
          import win.ui.shadow;
          win.ui.shadow(winform);
          
          //設置窗口縮放范圍
          import win.ui.minmax;
          win.ui.minmax(winform);
          
          //切換最大化、還原按鈕
          winform.adjust=function( cx,cy,wParam ) {
          	if( wParam==0x2/*_SIZE_MAXIMIZED*/ ){ 
          		wb.doScript(`document.getElementById("max-btn").innerText="2";`)
          	}
          	elseif( wParam==0x0/*_SIZE_RESTORED*/ ){
          		wb.doScript(`document.getElementById("max-btn").innerText="1";`)
          	} 
          };
          			
          winform.show();
          win.loopMessage();

          以上源碼來自 aardio 自帶范例 > Web 界面 > web.view :


          WebView2 + 前端工程

          如果熟悉網頁前端開發,也可以點擊 「 新建工程 > Web 界面 > WebView2 」創建工程。

          運行創建的范例工程會顯示幫助:

          這些熟悉前端的一看就懂,就不多說了。

          注意 WebView2 默認工程的「網頁源碼」這個目錄的「內嵌資源」屬性為 false —— 也就是說發布后的 EXE 文件不會包含這個目錄。

          而工程中的「網頁」目錄「內嵌資源」屬性為 true —— 也就是說發布后的 EXE 文件會包含這個目錄。

          「網頁」目錄「本地構建」屬性為 true —— 這指的是該目錄下的文件會無條件添加到發布 EXE 文件中(不必添加到工程 )。

          其他瀏覽器組件

          aardio 中的瀏覽器組件非常多,用法與 web.view 基本都類似。aardio 甚至可以調用操作系統已安裝的 Chrome,Edge 等瀏覽器寫軟件界面。

          請參考「 aardio 自帶范例 > Web 界面」:

          %20|%20Jeff

          幾周前,我花了兩天時間,將自己的%20WordPress%20網站做了個微信小程序版本。

          這篇文章,記錄的就是我自己在開發第一版小程序的過程。

          知曉程序(微信號%20zxcx0101)今天分享的這篇文章,將一步步講解,如何將一個%20WordPress%20網站借助%20REST%20API%20開發微信小程序版。

          關注「知曉程序」公眾號,在微信后臺回復「開發」,獲取小程序開發技巧精選文章。

          小程序如何讀取%20WordPress%20博客內容?

          WordPress%20在%204.6%20版本推出了%20REST%20API。簡單來說,它是一種通過%20HTTP%20請求完成的客戶端與服務端數據交互方案。

          我們訪問平常的普通%20WordPress%20網站,在沒有開啟靜態緩存的情況下,大致需要「從數據庫拉取數據%20→%20服務端%20PHP%20進程拼成%20HTML%20→%20用戶瀏覽器界面」的過程。

          REST%20API%20的處理過程類似,但稍微不同的是:輸出的是%20JSON%20格式的數據,且一般是給客戶端(非網頁瀏覽器)使用。

          有了%20REST%20API,一個網站制作不同客戶端(Android%20或%20iOS%20的%20app,以及微信小程序),而共享一個數據庫成為了可能。

          我們可通過瀏覽器,直接訪問%20WordPress%20的其中一個接口地址:

          your-site.com/wp-json/wp/v2/posts?per_page=5&page=1

          ,你可能會看到類似這樣的返回。

          現在,讓我將上面的%20URL%20解釋下。

          /wp-json/wp/v2/

          是WordPress%20定義的%20REST%20API%20路由(router)與版本號等的組合。

          posts

          在%20WordPress%20中,稱為「終點」(endpoint)。

          per_page

          page

          則是參數。

          上面的%20URL,表示輸出第%201%20頁最新%205%20篇文章的數據(5%20篇為%201%20頁)。

          微信小程序通過%20REST%20API,可以獲取到%20WordPress%20網站上的數據。對數據進行處理后,通過前端代碼渲染,就是你在微信客戶端上看到的界面。

          WordPress%20的%20REST%20API%20已經很完善了,什么文章數據、頁面數據、用戶數據等都不在話下。

          把%20WordPress%20作為小程序的后端,實在是省了不少人力,至少對我們這些前端狗來說,不用寫苦逼的后端代碼。

          開始動手,做一個%20WP%20小程序

          上一章節大致介紹了原理后,接下來就以本站開發的「DeveWork%20極客」小程序第一版為例,介紹三個頁面(首頁、內容頁、閱讀記錄頁)大體上是如何做出來的。

          1.%20準備工作

          準備工作就不細說,大體上包括如下操作。

          在微信公眾平臺管理后臺上注冊小程序賬號,配置合法域名等信息。

          二是服務端確保配置好%20HTTPS(但不一定要求備案)。

          另外在開始開發之前,我在服務端對%20WordPress%20REST%20API%20進行了一些定制化的輸出。

          2.%20項目結構

          結合微信官方%20quick%20start%20的例子與個人需求,將項目結構如下分好:

          .├──%20app.js├──%20app.json├──%20app.wxss%20├──%20config.js%20//%20配置文件├──%20image%20//%20圖片目錄├──%20pages%20//%20頁面目錄├──%20utils%20//%20實用%20untils%20類└──%20wxParse%20//%20第三方庫wxParse

          3.%20構建文章列表頁面

          小程序的首頁,就是文章列表頁面。啟動小程序時,會展示最新的%205%20篇文章,然后通過下拉流式加載更多文章。

          在這里,我們用到的%20WordPress%20REST%20API%20就是

          your-site.com/wp-json/wp/v2/posts?per_page={num}&page={num}

          index.js

          文件的核心,是通過

          wx.request

          接口,訪問上面的%20API%20URL%20獲取到文章數據,再

          setData

          進行渲染。

          //%20https://devework.com/wordpress-rest-api-weixin-weapp.htmlwx.request({%20%20%20%20url:%20url,%20%20%20%20success:%20function%20(response)%20{%20%20%20%20%20%20%20%20self.setData({%20%20%20%20%20%20%20%20%20%20%20%20posts:%20self.data.posts.concat(response.data.map(function%20(item)%20{%20%20%20%20%20%20%20%20%20%20%20%20%20...%20%20%20%20%20%20%20%20%20%20%20%20%20//%20數據過濾/格式化等%20%20%20%20%20%20%20%20%20%20%20%20%20...%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20item;%20%20%20%20%20%20%20%20%20%20%20%20}))%20%20%20%20%20%20%20%20});%20%20%20%20}%20%20});}

          我將這些代碼封裝在函數中,方便后續重復調用。

          設置的數據通過

          index.wxml

          循環輸出。因為要做滾動加載,所以采用了小程序的

          scroll-view

          組件。

          上面的%20WXML%20代碼中,綁定了兩個事件函數:一是下拉事件

          pullDownRefresh

          ,一個是點擊跳轉至文章頁面的事件

          redictSingle

          //%20下拉刷新pullDownRefresh:%20function%20(event)%20{%20%20%20%20var%20self%20=%20this;%20%20%20%20self.setData({%20%20%20%20%20%20%20%20page:%20self.data.page%20+%201%20//頁面+1%20%20%20%20});%20%20%20%20console.log('current%20page:'%20+%20self.data.page);%20%20%20%20this.fetchData({%20page:%20self.data.page%20});},%20//%20路由導航到文章內頁redictSingle:%20function%20(event)%20{%20%20%20%20console.log('redictSingle');%20%20%20%20var%20id%20=%20event.currentTarget.id;%20//%20這里的id%20其實是WordPress%20中的文章id,需要傳遞到single%20頁面%20%20%20%20var%20url%20=%20'../single/single?id='%20+%20id;%20%20%20%20wx.navigateTo({%20%20%20%20%20%20%20%20url:%20url%20%20%20%20})}

          4.%20構建文章詳情頁

          文章頁使用到的%20API%20地址是

          your-site.com/wp-json/wp/v2/posts/{id}

          。類似地,通過

          wx.request

          接口訪問%20URL,然后渲染數據到%20WXML%20頁面上。

          代碼與上面的類似,就不再重復。但需要提醒的是,這里涉及到如何將富文本轉為微信小程序可識別的%20WXML%20的問題。

          因為獲取的%20JSON%20數據中,文章正文部分是一段%20HTML%20代碼。如果將%20HTML%20直接輸出到小程序中,是會報錯的。

          我們需要將這段%20HTML%20代碼轉化為微信小程序%20WXML%20語言,下一章節我會介紹這個過程。

          4.%20閱讀記錄頁面

          閱讀記錄頁面是用來展示用戶瀏覽歷史,直接照著官方的%20Hello%20World%20例子就做起來了。

          這個頁面用到的主要如下兩種接口:本地緩存相關接口、用戶授權相關接口(

          wx.login

          wx.getUserInfo

          等)。

          從用戶體驗上考慮,不應該一開始就向用戶申請授權,而是有需要的頁面才申請。同時,也應該做好用戶拒絕授權的優雅處理。

          關注「知曉程序」微信公眾號,在微信后臺回復「用戶信息」,查看小程序如何正確地獲取用戶資料。

          記錄的文章閱讀歷史數據是以本地緩存的形式保存在客戶端,而非云端。所以,一句「閱讀記錄僅保存在本設備」的提示,是有必要的。

          同時,基于小程序緩存限制的考慮,我將記錄上限設為%2020%20篇。

          //%20調用API從本地緩存中獲取閱讀記錄并記錄var%20logs%20=%20wx.getStorageSync('readLogs')%20||%20;//%20過濾重復值if%20(logs.length%20>%200)%20{%20%20%20%20logs%20=%20logs.filter(function%20(log)%20{%20%20%20%20%20%20%20%20return%20log[0]%20!==%20id;%20%20%20%20});}//%20如果超過指定數量if%20(logs.length%20>%2019)%20{%20%20%20%20logs.pop;//去除最后一個}%20logs.unshift([id,%20response.data.title.rendered]);wx.setStorageSync('readLogs',%20logs);

          上面的代碼,其實是放在

          single.js

          里面的。因為我需要將文章%20ID%20與標題保存,而只有

          single.js

          ,才會同時獲取這兩種數據。

          最后,我還需要在

          log.js

          onShow

          生命周期函數中,綁定一個更新數據的函數:

          updateData:%20function(cb){%20%20var%20that%20=%20this;%20%20//%20readlog%20%20%20this.setData({%20%20%20%20readLogs:%20(wx.getStorageSync('readLogs')%20||%20).map(function%20(log)%20{%20%20%20%20%20%20return%20log;%20%20%20%20})%20%20})},

          開發過程中,我踩的坑

          這個章節主要記錄在開發過程中的一些坑,以及我所采用的解決方案。

          1.%20Tab%20Bar%20的圖片問題

          小程序官方宣稱支持%20SVG%20圖片,但%20tab%20bar%20并不支持%20SVG%20圖片。

          官方推薦采用%2081%20px%20×%2081%20px%20尺寸的%20PNG%20圖片,但這個依然有點坑。

          建議在設計%20icon%20的時候,為%20tab%20bar%20的圖標稍微留點透明的%20padding,不然,圖標在真機上會放得很大。

          2.%20圖片防盜鏈的%20referer%20設置

          如果你托管圖片的服務器有防盜鏈處理,那么得將

          servicewechat.com

          放入白名單中。記得,這個白名單不是

          qq.com

          3.

          image

          組件的絕對路徑,必須以%20HTTPS%20開頭

          image

          組件的

          src

          絕對路徑,在%20web%20開發中是允許類似

          //example.com/pic.png

          這種省略協議名的存在。

          這種圖片路徑,在微信 web 開發者工具也能正常顯示。但是,在真機上就不能正常加載了。在真機上必須是 HTTPS 開頭的絕對路徑。

          服務端數據側不好處理的話,可以通過下面的函數處理:

          // 補全URL 中缺失的 HTTPSfunction addhttps(url) { if (!/^(f|ht)tps?:\/\//i.test(url)) { url="https:" + url; } return url;}

          4. 開發者工具的小程序 UA 與實際 UA 不同

          開發工具中模擬的小程序 UA 類似這樣:

          ... Chrome/53.0.2785.143 Safari/537.36 appservice webview/100000

          而通過 Nginx 的 log,我們可以知道,真機運行的 UA 其實就是微信的 UA:

          ... Mobile/14E304 MicroMessenger/6.6.0 NetType/WIFI Language/zh_CN

          某些情況下需要注意這些不同。

          5. 默認的 Flex 布局

          如果你是在官方例子的代碼基礎上開發你的小程序的,建議先刪掉

          app.wxss

          的 Flex 布局相關代碼。這樣做,會降低你遇到奇葩樣式問題的概率。

          6. wxParse 的坑

          小程序使用到的富文本轉化是用 wxParse 這個第三方庫,用的時候發現有不少坑(但目前是這個庫最為實用了)。

          其中一個,就是全局的 code 字符都被替換為

          wx-codexxx

          ,作者本意應該是對 code 標簽進行這個替換,但可能一不小心寫錯了。

          解決方案,只能是暫時刪掉那段代碼。

          另外,使用 wxParse 的時候,

          image

          組件中的

          src

          屬性,會多解析出一個逗號。

          看圖說話:

          上圖也很好解釋了上面的 referer 坑與圖片路徑 HTTPS 開頭的坑。解決方案,只能先改動源碼(

          html2json.js

          )來修復:

          // Fix: img 標簽數組含有空字符的問題if (imgUrl[0]==''){ imgUrl.splice(0, 1);}

          關于富文本,好消息是,官方的富文本組件已經發布。

          關注「知曉程序」微信公眾號,在微信后臺回復「富文本」,查看小程序富文本組件新能力解讀。

          最后的話

          至此,我也算是詳略得當地,介紹了開發 WordPress 版小程序的過程。接下來的工作,自然是提交到官方并耐心等待審核結果的通知。

          整個開發過程其實并不太有難度,如果之前有使用過 Angular、Vue 這類 MVVM 框架,整個開發過程基本上只是看官方文檔的問題。

          「DeveWork 極客」小程序使用鏈接

          https://minapp.com/miniapp/3016/

          原文地址:https://devework.com/wordpress-rest-api-weixin-weapp.html

          以下為網友評論:

          網友“小103224036”:官方的富文本也不好用

          網友“FG云視頻”:你以為說這么詳細我就懂了嗎,太天真了[來看我][來看我]

          網友“偶偶30498586”:太高大上了 看不懂

          網友“詹姆士張”:小程序能推送嗎?

          網友“一抹天真丟失在了曾經”:[愛慕]

          尋找熱愛表達的你#


          "一鍵將網頁截圖制作成HTML網頁"是指一種技術,它允許用戶通過簡單的操作,將網頁的截圖轉換成HTML代碼的網頁。這通常涉及到自動布局、樣式提取和代碼生成。以下是實現這一功能的相關技術和步驟:

          1. 截圖捕捉:首先,需要有一個方法來捕捉網頁的截圖,這可以通過瀏覽器插件、屏幕捕獲工具或專門的應用程序來完成。

          2. 圖像處理:捕捉到的截圖可能需要進行預處理,比如裁剪、壓縮或調整分辨率,以確保圖像的質量。

          3. 元素識別:使用圖像識別技術來分析截圖,識別網頁中的元素,比如文本、按鈕、圖片等。

          4. 布局分析:基于識別出的元素,分析頁面的布局信息,包括元素的大小、位置和層級。

          5. 樣式解析:提取頁面的樣式信息,包括顏色、字體、間距等,并將它們轉換為CSS代碼。

          6. HTML生成:根據布局和樣式信息,生成HTML結構代碼,將截圖中的元素轉換為HTML標簽。

          7. 代碼優化:對生成的HTML代碼進行優化,確保代碼的可讀性、維護性和性能。

          8. 響應式設計:確保生成的網頁代碼能夠適應不同的屏幕尺寸和設備,實現響應式布局。

          9. 交互性實現:如果截圖中的頁面包含交互元素,需要添加相應的JavaScript代碼來實現這些交互。

          10. 一鍵操作:提供一個簡單的用戶界面,用戶只需點擊一個按鈕,就可以完成截圖到HTML的轉換。

          11. 預覽功能:在轉換過程中提供實時預覽,讓用戶可以實時看到轉換效果。

          12. 自定義選項:允許用戶對生成的HTML代碼進行自定義,比如修改布局、添加額外的樣式或功能。

          13. 保存和導出:用戶可以保存或導出生成的HTML代碼,以便進一步使用或分享。

          14. 錯誤處理:在轉換過程中識別和處理潛在的錯誤,比如布局沖突或樣式問題。

          15. 兼容性測試:確保生成的網頁在不同的瀏覽器和設備上都能正常顯示和工作。

          16. 安全性考慮:生成的代碼應遵循安全最佳實踐,避免潛在的安全風險。

          17. 用戶反饋:收集用戶反饋,不斷改進轉換算法和用戶體驗。

          18. 開源和社區支持:作為開源項目,鼓勵社區參與貢獻代碼和改進功能。

          這種一鍵轉換技術可以大大提高網頁開發的效率,尤其是對于快速原型設計和演示目的。然而,需要注意的是,自動生成的代碼可能需要進一步的人工審查和調整,以確保最終產品的質量和性能。此外,一些復雜的網頁效果和動態交互可能需要手動編寫代碼來實現。


          主站蜘蛛池模板: 日日摸夜夜添一区| 亚洲午夜精品一区二区公牛电影院| 国产一区视频在线| 波多野结衣一区二区三区| 又硬又粗又大一区二区三区视频 | 国精产品一区一区三区MBA下载 | 日韩三级一区二区| 少妇精品久久久一区二区三区| 国产一区二区在线观看app| 国产在线精品观看一区| 国产午夜精品一区二区三区极品 | 国产高清一区二区三区四区| 成人精品一区久久久久| 国产在线观看精品一区二区三区91| 高清精品一区二区三区一区| 无码播放一区二区三区| 无码播放一区二区三区| 亚洲AV无码一区二区三区网址| 91精品乱码一区二区三区| 蜜臀AV一区二区| 欲色aV无码一区二区人妻| 无码人妻一区二区三区兔费| 成人丝袜激情一区二区| 国产精品亚洲综合一区在线观看| 国产一区二区三区小说| 波多野结衣在线观看一区二区三区| 日韩精品一区在线| 波多野结衣一区二区免费视频| 一区二区日韩国产精品| 伦理一区二区三区| 一区二区三区在线|欧| 精品视频一区二区三区四区| 日本精品3d动漫一区二区| 无码人妻精品一区二| 日本一区二区在线| 一本一道波多野结衣一区| 色欲AV无码一区二区三区| 韩国福利一区二区三区高清视频| 亚洲av午夜福利精品一区人妖| 99精品国产一区二区三区2021| 国产精品区一区二区三|