整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

放弃 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. 开源和社区支持:作为开源项目,鼓励社区参与贡献代码和改进功能。

这种一键转换技术可以大大提高网页开发的效率,尤其是对于快速原型设计和演示目的。然而,需要注意的是,自动生成的代码可能需要进一步的人工审查和调整,以确保最终产品的质量和性能。此外,一些复杂的网页效果和动态交互可能需要手动编写代码来实现。