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
lectron 不錯,但也不是完美的。
Electron 帶來了很多優(yōu)秀的桌面軟件,但并不一定總是適合我們的需求。
多個選擇總是好事!
1、Electron 太大了!
2、每一個 Electron 寫的軟件都要重復(fù)地帶一個 Electron …… 升級與分發(fā)都不方便。
3、Electron 不方便嵌入其他窗口界面,與其他語言、技術(shù)融合不易。
4、并不是所有桌面軟件都需要 Electron 的跨平臺特性。macOS , Linux 的桌面系統(tǒng)市場份額小于被遺忘的 Windows 8 ,如果軟件只是在 Windows 平臺運行,并且需要大量與專用系統(tǒng) API 交互,跨平臺反而是不必要的負(fù)擔(dān)。
5、我曾經(jīng)在 aardio 中封裝了一個 electron 擴展庫,然后我在寫這個擴展庫的時候,當(dāng)時看到的還是 remote 真香 …… 然后我為這個擴展庫寫了個很大的 JS 文件就用到了 remote。可是等我寫完沒多久, 就看到 remote 被 Electron 拋棄了,remote 會慢一萬倍 ,各種缺陷 ……
1、WebView2 基于性能強悍的 Edge(Chromium) 內(nèi)核。
2、調(diào)用 WebView2 生成的軟件體積很小。所有基于 WebView2 的軟件可以共享同一個 WebView2 組件。Win11 已經(jīng)內(nèi)置 WebView2 組件,其他操作系統(tǒng)也可以快速地自動安裝 WebView2 。
3、WebView2 接口非常簡潔,嵌入其他窗口界面也非常方便。
總結(jié)一句話就是:WebView2 簡單、好用、生成軟件體積小。
aardio 標(biāo)準(zhǔn)庫中的 web.view 就是基于 WebView2。WebView2 的接口是如此簡潔,所以我寫的這個庫也只有很少的代碼。因為 aardio 可以將網(wǎng)頁自動內(nèi)嵌到獨立 EXE 文件,就可以非常方便地生成獨立 EXE 程序。
下面我們用 aardio 調(diào)用 web.view (WebView2)寫一個最簡單的程序:
import win.ui;
/*DSG{{*/
mainForm=win.form(text="WebView2")
mainForm.add(
btnCallJs={cls="button";text="調(diào)用 JS 函數(shù)";left=461;top=395;right=726;bottom=449;note="點這里調(diào)用 JavaScript 函數(shù)";z=1};
custom={cls="custom";left=17;top=21;right=730;bottom=356;z=2}
)
/*}}*/
//創(chuàng)建瀏覽器組件
import web.view;
var wb=web.view(mainForm.custom);
//導(dǎo)出本地函數(shù)給網(wǎng)頁 JavaScript
wb.external={
getComputerName=function(){
return sys.getComputerName();
}
}
import sys;
//寫入網(wǎng)頁 HTML
wb.html=/**
<html>
<head>
<script>
(async ()=>{
var n=await aardio.getComputerName();
alert(n);
})()
</script>
</head>
<body>
**/
//響應(yīng)按鈕事件
mainForm.btnCallJs.oncommand=function(id,event){
//調(diào)用 JS 函數(shù)
wb.xcall("document.write","測試")
}
mainForm.show();
win.loopMessage();
對,這就是一個完整程序的源代碼,可以一鍵生成獨立 EXE 文件。
首先點選 「aardio 主菜單 > 新建工程 > 窗口程序 > 空白工程」,然后點擊「創(chuàng)建工程」。
如果熟悉網(wǎng)頁前端開發(fā),也可以點擊 「 新建工程 > Web 界面 > WebView2 」創(chuàng)建工程。
雙擊工程入口代碼 main.aardio 打開主窗口,自「界面控件」中拖一個 「調(diào)用 JS 函數(shù)」的按鈕上去,再拖一個 custom 控件到窗體上 —— 用來嵌入網(wǎng)頁:
然后切換到代碼視圖,添加以下代碼創(chuàng)建網(wǎng)頁瀏覽器:
import web.view;
var wb=web.view(mainForm.custom);
web.view 的第 1 個參數(shù)指定要嵌入 WebView2 的窗口對象,該參數(shù)可以是 mainForm.custom 這樣的控件窗口,也可以是 mainForm 這樣的窗體對象。
下面使用
wb.html="<html></html>"
就可以寫網(wǎng)頁 HTML 代碼了。
或者使用
wb.go("網(wǎng)址")
可以打開指定的網(wǎng)頁。
使用
import wsock.tcp.simpleHttpServer;
wb.go("\res\index.html");
可以打開資源目錄的網(wǎng)頁,支持SPA 單頁應(yīng)用。資源目錄可以嵌入 EXE 生成 獨立 EXE 文件,放心不用多寫其他代碼。
添加下面的代碼導(dǎo)出 external 對象給網(wǎng)頁 JavaScript :
//導(dǎo)出本地函數(shù)給網(wǎng)頁 JavaScript
wb.external={
getComputerName=function(){
return sys.getComputerName();
}
}
import sys;
在網(wǎng)頁 JavaScript 里可以調(diào)用上面導(dǎo)出的 external 對象,不過在 JavaScript 里要用 aardio 這個名字表示 external 對象,網(wǎng)頁代碼如下:
wb.html=/**
<html>
<head>
<script>
(async ()=>{
var n=await aardio.getComputerName();
alert(n);
})()
</script>
</head>
<body>
**/
注意在 aardio 中 /* 注釋 */ 可以作為字符串賦值給其他變量,請參考:aardio 編程語言快速入門——語法速覽
要注意所有 aardio 對象在 JavaScript 中都是異步 Promise 對象。如上在 async 函數(shù)體內(nèi)可以愉快地使用 await 調(diào)用 aardio 函數(shù) —— 這非常方便。
我們在窗體設(shè)計視圖雙擊「調(diào)用 JS 函數(shù)」按鈕,這會切換到代碼視圖,并自動添加以下回調(diào)函數(shù):
mainForm.btnCallJs.oncommand=function(id,event){
}
用戶點擊按鈕時就會調(diào)用上面的函數(shù)。
小改一下添加 aardio 代碼調(diào)用 JavaScript 函數(shù):
//響應(yīng)按鈕事件
mainForm.btnCallJs.oncommand=function(id,event){
//調(diào)用 JS 函數(shù)
wb.xcall("document.write","測試")
}
很簡單,一個程序就寫好了。可以在 aardio 中點擊「運行」按鈕直接運行代碼,也可以點擊「發(fā)布」按鈕直接生成 EXE 文件。
web.view() 構(gòu)造函數(shù)的第 1 個嵌入窗口參數(shù)可以是 win.form 對象(獨立窗口),也可以是 custom, static 這樣的普通控件對象。例如前面的例子就是將 WebView2 嵌入 custom 控件:
import web.view;
var wb=web.view(mainForm.custom);
aardio 中的所有控件都可以非常方便的支持自動縮放。只要簡單地在窗體設(shè)計器中選定控件,然后在「屬性」面板設(shè)置「固定邊距」、「自適應(yīng)大小」這些屬性就可以。
一個更簡單的方法是在窗體設(shè)計器上點右鍵,然后在彈出菜單中點擊「九宮格縮放布局」—— aardio 將會自動設(shè)置所有控件的自適應(yīng)縮放屬性。
至于網(wǎng)頁內(nèi)容自適應(yīng)排版很簡單,不需要在 aardio 中編寫代碼。
前面我們介紹過使用 external 導(dǎo)出 aardio 函數(shù)到網(wǎng)頁 JavaScript 。我們還可以用 wb.export 導(dǎo)出 aardio 函數(shù),先看例子:
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() 導(dǎo)出的是 JavaScript 全局函數(shù)。
2、wb.export() 導(dǎo)出的函數(shù)在 JavaScript 中同樣是異步 Promise 對象。
3、wb.export() 導(dǎo)出的 Javascript 全局函數(shù), 使用 JSON 自動轉(zhuǎn)換調(diào)用參數(shù)和返回值,可以更好的兼容只能支持純 aardio 對象 / 純 JavaScript 對象的代碼。
4、wb.export() 導(dǎo)出的函數(shù)內(nèi)部禁止調(diào)用 wb.doScript 或 wb.eval 執(zhí)行Javascript 。
wb.external 內(nèi)部是調(diào)用 wb.exportHostObject() 導(dǎo)出 aardio 對象,中間不需要經(jīng)過 JSON 自動轉(zhuǎn)換。
我經(jīng)常被問到幾個類似的問題:
1、JavaScript 的異步函數(shù)太麻煩了,怎樣把他搞成同步的,不用 await ,不用 async 。
2、JavaScript 的異步函數(shù)太好用了,怎樣在 aardio 中也這樣搞,如何在 aardio 里 await 。
其實同步有同步的優(yōu)勢,異步有異步的好處,揚長避短是智慧,倒行逆施最累人。下面我們一起來寫一個在 WebView2 中調(diào)用本地 Ping 命令的小程序體驗一下。
第一步:創(chuàng)建窗口。
import win.ui;
var winform=win.form(text="Ping")
第二步:基于窗口創(chuàng)建 WebView2 瀏覽器組件。
import web.view;
var wb=web.view(winform);
第三步:使用 external 對象導(dǎo)出 JavaScript 可以調(diào)用的本地函數(shù)。
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() 就可以直接調(diào)用上面的 external.ping() 函數(shù)了。
第四步:下面在網(wǎng)頁里寫 JavaScript 來調(diào)用 aardio 函數(shù)。
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 源代碼如下:
//創(chuàng)建窗口
import win.ui;
var winform=win.form(text="Ping")
//嵌入瀏覽器組件
import web.view;
var wb=web.view(winform);
//導(dǎo)出 aardio 函數(shù)到 JavaScript
wb.external={
ping=function(domain){
//同步有同步的優(yōu)勢,揚長避短是智慧,倒行逆施最累人。
var prcs=process.popen("ping "+ domain);
for( all,out,err in prcs.each() ){
wb.invoke("document.body.insertAdjacentText",'beforeend',all);
}
return "恭喜,事做好了!"
}
}
import process.popen;
//寫入網(wǎng)頁 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();
//啟動界面消息循環(huán)
win.loopMessage();
在 aardio 中可以使用 wb.doScript() , wb.eval() , wb.xcall() 等函數(shù)調(diào)用網(wǎng)頁 JavaScript ,下面看一個在 aardio 中調(diào)用 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();
「無邊框窗口」指的是去掉獨立窗體默認(rèn)的邊框與標(biāo)題欄,然后由程序自行定制邊框與標(biāo)題欄。
aardio 做這事還是很容易的,首頁在窗體屬性中指定「邊框」屬性為 none。
這樣直接運行后顯示的窗體就沒有邊框和標(biāo)題欄了( 按 Alt + F4 關(guān)閉窗口 )。
然后添加下面的代碼就可以為窗體添加標(biāo)題欄、標(biāo)題欄按鈕、陰影邊框、并支持拖動邊框縮放:
import win.ui.simpleWindow;
win.ui.simpleWindow(winform);
win.ui.simpleWindow 的源碼很簡單,參考其源碼也可以自己編寫新的庫定制邊框與標(biāo)題欄。
這里我們不用上面的方法,而是用網(wǎng)頁實現(xiàn)標(biāo)題欄。
我們知道網(wǎng)頁繪制一個標(biāo)題欄與標(biāo)題欄按鈕很簡單,難點在于怎么在網(wǎng)頁里控制窗口。我們先學(xué)習(xí)幾個專用于無邊框窗口的 aardio 函數(shù):
winform.hitMax() //模擬點擊最大化按鈕
winform.hitMin() //模擬點擊最小化按鈕
winform.hitClose() //模擬點擊關(guān)閉按鈕
winform.hitCaption() //拖動標(biāo)題欄
下面寫個簡單的例子,先看下運行效果:
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);
//導(dǎo)出為 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()">按住這里調(diào)用 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 ,創(chuàng)建無邊框窗口。<br />
2、調(diào)用 win.ui.shadow(winform) 創(chuàng)建陰影邊框<br />
</div>
<script src="default.js"></script>
</body>
</html>
**/
//添加陰影邊框
import win.ui.shadow;
win.ui.shadow(winform);
//設(shè)置窗口縮放范圍
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 :
如果熟悉網(wǎng)頁前端開發(fā),也可以點擊 「 新建工程 > Web 界面 > WebView2 」創(chuàng)建工程。
運行創(chuàng)建的范例工程會顯示幫助:
這些熟悉前端的一看就懂,就不多說了。
注意 WebView2 默認(rèn)工程的「網(wǎng)頁源碼」這個目錄的「內(nèi)嵌資源」屬性為 false —— 也就是說發(fā)布后的 EXE 文件不會包含這個目錄。
而工程中的「網(wǎng)頁」目錄「內(nèi)嵌資源」屬性為 true —— 也就是說發(fā)布后的 EXE 文件會包含這個目錄。
「網(wǎng)頁」目錄「本地構(gòu)建」屬性為 true —— 這指的是該目錄下的文件會無條件添加到發(fā)布 EXE 文件中(不必添加到工程 )。
aardio 中的瀏覽器組件非常多,用法與 web.view 基本都類似。aardio 甚至可以調(diào)用操作系統(tǒng)已安裝的 Chrome,Edge 等瀏覽器寫軟件界面。
請參考「 aardio 自帶范例 > Web 界面」:
%20|%20Jeff
幾周前,我花了兩天時間,將自己的%20WordPress%20網(wǎng)站做了個微信小程序版本。
這篇文章,記錄的就是我自己在開發(fā)第一版小程序的過程。
知曉程序(微信號%20zxcx0101)今天分享的這篇文章,將一步步講解,如何將一個%20WordPress%20網(wǎng)站借助%20REST%20API%20開發(fā)微信小程序版。
關(guān)注「知曉程序」公眾號,在微信后臺回復(fù)「開發(fā)」,獲取小程序開發(fā)技巧精選文章。
小程序如何讀取%20WordPress%20博客內(nèi)容?
WordPress%20在%204.6%20版本推出了%20REST%20API。簡單來說,它是一種通過%20HTTP%20請求完成的客戶端與服務(wù)端數(shù)據(jù)交互方案。
我們訪問平常的普通%20WordPress%20網(wǎng)站,在沒有開啟靜態(tài)緩存的情況下,大致需要「從數(shù)據(jù)庫拉取數(shù)據(jù)%20→%20服務(wù)端%20PHP%20進程拼成%20HTML%20→%20用戶瀏覽器界面」的過程。
REST%20API%20的處理過程類似,但稍微不同的是:輸出的是%20JSON%20格式的數(shù)據(jù),且一般是給客戶端(非網(wǎng)頁瀏覽器)使用。
有了%20REST%20API,一個網(wǎng)站制作不同客戶端(Android%20或%20iOS%20的%20app,以及微信小程序),而共享一個數(shù)據(jù)庫成為了可能。
我們可通過瀏覽器,直接訪問%20WordPress%20的其中一個接口地址:
your-site.com/wp-json/wp/v2/posts?per_page=5&page=1
,你可能會看到類似這樣的返回。
現(xiàn)在,讓我將上面的%20URL%20解釋下。
/wp-json/wp/v2/
是WordPress%20定義的%20REST%20API%20路由(router)與版本號等的組合。
posts
在%20WordPress%20中,稱為「終點」(endpoint)。
per_page
與
page
則是參數(shù)。
上面的%20URL,表示輸出第%201%20頁最新%205%20篇文章的數(shù)據(jù)(5%20篇為%201%20頁)。
微信小程序通過%20REST%20API,可以獲取到%20WordPress%20網(wǎng)站上的數(shù)據(jù)。對數(shù)據(jù)進行處理后,通過前端代碼渲染,就是你在微信客戶端上看到的界面。
WordPress%20的%20REST%20API%20已經(jīng)很完善了,什么文章數(shù)據(jù)、頁面數(shù)據(jù)、用戶數(shù)據(jù)等都不在話下。
把%20WordPress%20作為小程序的后端,實在是省了不少人力,至少對我們這些前端狗來說,不用寫苦逼的后端代碼。
開始動手,做一個%20WP%20小程序
上一章節(jié)大致介紹了原理后,接下來就以本站開發(fā)的「DeveWork%20極客」小程序第一版為例,介紹三個頁面(首頁、內(nèi)容頁、閱讀記錄頁)大體上是如何做出來的。
1.%20準(zhǔn)備工作
準(zhǔn)備工作就不細(xì)說,大體上包括如下操作。
在微信公眾平臺管理后臺上注冊小程序賬號,配置合法域名等信息。
二是服務(wù)端確保配置好%20HTTPS(但不一定要求備案)。
另外在開始開發(fā)之前,我在服務(wù)端對%20WordPress%20REST%20API%20進行了一些定制化的輸出。
2.%20項目結(jié)構(gòu)
結(jié)合微信官方%20quick%20start%20的例子與個人需求,將項目結(jié)構(gòu)如下分好:
.├──%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構(gòu)建文章列表頁面
小程序的首頁,就是文章列表頁面。啟動小程序時,會展示最新的%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獲取到文章數(shù)據(jù),再
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數(shù)據(jù)過濾/格式化等%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});}
我將這些代碼封裝在函數(shù)中,方便后續(xù)重復(fù)調(diào)用。
設(shè)置的數(shù)據(jù)通過
index.wxml
循環(huán)輸出。因為要做滾動加載,所以采用了小程序的
scroll-view
組件。
上面的%20WXML%20代碼中,綁定了兩個事件函數(shù):一是下拉事件
pullDownRefresh
,一個是點擊跳轉(zhuǎn)至文章頁面的事件
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路由導(dǎo)航到文章內(nèi)頁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構(gòu)建文章詳情頁
文章頁使用到的%20API%20地址是
your-site.com/wp-json/wp/v2/posts/{id}
。類似地,通過
wx.request
接口訪問%20URL,然后渲染數(shù)據(jù)到%20WXML%20頁面上。
代碼與上面的類似,就不再重復(fù)。但需要提醒的是,這里涉及到如何將富文本轉(zhuǎn)為微信小程序可識別的%20WXML%20的問題。
因為獲取的%20JSON%20數(shù)據(jù)中,文章正文部分是一段%20HTML%20代碼。如果將%20HTML%20直接輸出到小程序中,是會報錯的。
我們需要將這段%20HTML%20代碼轉(zhuǎn)化為微信小程序%20WXML%20語言,下一章節(jié)我會介紹這個過程。
4.%20閱讀記錄頁面
閱讀記錄頁面是用來展示用戶瀏覽歷史,直接照著官方的%20Hello%20World%20例子就做起來了。
這個頁面用到的主要如下兩種接口:本地緩存相關(guān)接口、用戶授權(quán)相關(guān)接口(
wx.login
,
wx.getUserInfo
等)。
從用戶體驗上考慮,不應(yīng)該一開始就向用戶申請授權(quán),而是有需要的頁面才申請。同時,也應(yīng)該做好用戶拒絕授權(quán)的優(yōu)雅處理。
關(guān)注「知曉程序」微信公眾號,在微信后臺回復(fù)「用戶信息」,查看小程序如何正確地獲取用戶資料。
記錄的文章閱讀歷史數(shù)據(jù)是以本地緩存的形式保存在客戶端,而非云端。所以,一句「閱讀記錄僅保存在本設(shè)備」的提示,是有必要的。
同時,基于小程序緩存限制的考慮,我將記錄上限設(shè)為%2020%20篇。
//%20調(diào)用API從本地緩存中獲取閱讀記錄并記錄var%20logs%20=%20wx.getStorageSync('readLogs')%20||%20;//%20過濾重復(fù)值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如果超過指定數(shù)量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與標(biāo)題保存,而只有
single.js
,才會同時獲取這兩種數(shù)據(jù)。
最后,我還需要在
log.js
的
onShow
生命周期函數(shù)中,綁定一個更新數(shù)據(jù)的函數(shù):
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})},
開發(fā)過程中,我踩的坑
這個章節(jié)主要記錄在開發(fā)過程中的一些坑,以及我所采用的解決方案。
1.%20Tab%20Bar%20的圖片問題
小程序官方宣稱支持%20SVG%20圖片,但%20tab%20bar%20并不支持%20SVG%20圖片。
官方推薦采用%2081%20px%20×%2081%20px%20尺寸的%20PNG%20圖片,但這個依然有點坑。
建議在設(shè)計%20icon%20的時候,為%20tab%20bar%20的圖標(biāo)稍微留點透明的%20padding,不然,圖標(biāo)在真機上會放得很大。
2.%20圖片防盜鏈的%20referer%20設(shè)置
如果你托管圖片的服務(wù)器有防盜鏈處理,那么得將
servicewechat.com
放入白名單中。記得,這個白名單不是
qq.com
。
3.
image
組件的絕對路徑,必須以%20HTTPS%20開頭
image
組件的
src
絕對路徑,在%20web%20開發(fā)中是允許類似
//example.com/pic.png
這種省略協(xié)議名的存在。
這種圖片路徑,在微信 web 開發(fā)者工具也能正常顯示。但是,在真機上就不能正常加載了。在真機上必須是 HTTPS 開頭的絕對路徑。
服務(wù)端數(shù)據(jù)側(cè)不好處理的話,可以通過下面的函數(shù)處理:
// 補全URL 中缺失的 HTTPSfunction addhttps(url) { if (!/^(f|ht)tps?:\/\//i.test(url)) { url="https:" + url; } return url;}
4. 開發(fā)者工具的小程序 UA 與實際 UA 不同
開發(fā)工具中模擬的小程序 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. 默認(rèn)的 Flex 布局
如果你是在官方例子的代碼基礎(chǔ)上開發(fā)你的小程序的,建議先刪掉
app.wxss
的 Flex 布局相關(guān)代碼。這樣做,會降低你遇到奇葩樣式問題的概率。
6. wxParse 的坑
小程序使用到的富文本轉(zhuǎn)化是用 wxParse 這個第三方庫,用的時候發(fā)現(xiàn)有不少坑(但目前是這個庫最為實用了)。
其中一個,就是全局的 code 字符都被替換為
wx-codexxx
,作者本意應(yīng)該是對 code 標(biāo)簽進行這個替換,但可能一不小心寫錯了。
解決方案,只能是暫時刪掉那段代碼。
另外,使用 wxParse 的時候,
image
組件中的
src
屬性,會多解析出一個逗號。
看圖說話:
上圖也很好解釋了上面的 referer 坑與圖片路徑 HTTPS 開頭的坑。解決方案,只能先改動源碼(
html2json.js
)來修復(fù):
// Fix: img 標(biāo)簽數(shù)組含有空字符的問題if (imgUrl[0]==''){ imgUrl.splice(0, 1);}
關(guān)于富文本,好消息是,官方的富文本組件已經(jīng)發(fā)布。
關(guān)注「知曉程序」微信公眾號,在微信后臺回復(fù)「富文本」,查看小程序富文本組件新能力解讀。
最后的話
至此,我也算是詳略得當(dāng)?shù)兀榻B了開發(fā) WordPress 版小程序的過程。接下來的工作,自然是提交到官方并耐心等待審核結(jié)果的通知。
整個開發(fā)過程其實并不太有難度,如果之前有使用過 Angular、Vue 這類 MVVM 框架,整個開發(fā)過程基本上只是看官方文檔的問題。
「DeveWork 極客」小程序使用鏈接
https://minapp.com/miniapp/3016/
原文地址:https://devework.com/wordpress-rest-api-weixin-weapp.html
以下為網(wǎng)友評論:
網(wǎng)友“小103224036”:官方的富文本也不好用
網(wǎng)友“FG云視頻”:你以為說這么詳細(xì)我就懂了嗎,太天真了[來看我][來看我]
網(wǎng)友“偶偶30498586”:太高大上了 看不懂
網(wǎng)友“詹姆士張”:小程序能推送嗎?
網(wǎng)友“一抹天真丟失在了曾經(jīng)”:[愛慕]
尋找熱愛表達的你#
"一鍵將網(wǎng)頁截圖制作成HTML網(wǎng)頁"是指一種技術(shù),它允許用戶通過簡單的操作,將網(wǎng)頁的截圖轉(zhuǎn)換成HTML代碼的網(wǎng)頁。這通常涉及到自動布局、樣式提取和代碼生成。以下是實現(xiàn)這一功能的相關(guān)技術(shù)和步驟:
1. 截圖捕捉:首先,需要有一個方法來捕捉網(wǎng)頁的截圖,這可以通過瀏覽器插件、屏幕捕獲工具或?qū)iT的應(yīng)用程序來完成。
2. 圖像處理:捕捉到的截圖可能需要進行預(yù)處理,比如裁剪、壓縮或調(diào)整分辨率,以確保圖像的質(zhì)量。
3. 元素識別:使用圖像識別技術(shù)來分析截圖,識別網(wǎng)頁中的元素,比如文本、按鈕、圖片等。
4. 布局分析:基于識別出的元素,分析頁面的布局信息,包括元素的大小、位置和層級。
5. 樣式解析:提取頁面的樣式信息,包括顏色、字體、間距等,并將它們轉(zhuǎn)換為CSS代碼。
6. HTML生成:根據(jù)布局和樣式信息,生成HTML結(jié)構(gòu)代碼,將截圖中的元素轉(zhuǎn)換為HTML標(biāo)簽。
7. 代碼優(yōu)化:對生成的HTML代碼進行優(yōu)化,確保代碼的可讀性、維護性和性能。
8. 響應(yīng)式設(shè)計:確保生成的網(wǎng)頁代碼能夠適應(yīng)不同的屏幕尺寸和設(shè)備,實現(xiàn)響應(yīng)式布局。
9. 交互性實現(xiàn):如果截圖中的頁面包含交互元素,需要添加相應(yīng)的JavaScript代碼來實現(xiàn)這些交互。
10. 一鍵操作:提供一個簡單的用戶界面,用戶只需點擊一個按鈕,就可以完成截圖到HTML的轉(zhuǎn)換。
11. 預(yù)覽功能:在轉(zhuǎn)換過程中提供實時預(yù)覽,讓用戶可以實時看到轉(zhuǎn)換效果。
12. 自定義選項:允許用戶對生成的HTML代碼進行自定義,比如修改布局、添加額外的樣式或功能。
13. 保存和導(dǎo)出:用戶可以保存或?qū)С錾傻腍TML代碼,以便進一步使用或分享。
14. 錯誤處理:在轉(zhuǎn)換過程中識別和處理潛在的錯誤,比如布局沖突或樣式問題。
15. 兼容性測試:確保生成的網(wǎng)頁在不同的瀏覽器和設(shè)備上都能正常顯示和工作。
16. 安全性考慮:生成的代碼應(yīng)遵循安全最佳實踐,避免潛在的安全風(fēng)險。
17. 用戶反饋:收集用戶反饋,不斷改進轉(zhuǎn)換算法和用戶體驗。
18. 開源和社區(qū)支持:作為開源項目,鼓勵社區(qū)參與貢獻代碼和改進功能。
這種一鍵轉(zhuǎn)換技術(shù)可以大大提高網(wǎng)頁開發(fā)的效率,尤其是對于快速原型設(shè)計和演示目的。然而,需要注意的是,自動生成的代碼可能需要進一步的人工審查和調(diào)整,以確保最終產(chǎn)品的質(zhì)量和性能。此外,一些復(fù)雜的網(wǎng)頁效果和動態(tài)交互可能需要手動編寫代碼來實現(xiàn)。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。