迷你应用标记、样式、脚本和更新

如前所述,迷你应用是使用 HTML 方言编写的,而不是使用纯 HTML。如果您曾处理过 Vue.js 文本插值和指令,就会立刻熟悉,但在此之前,XML 转换 (XSLT) 中就已有类似的概念。下方显示了微信 WXML 中的代码示例,但所有微应用平台(即支付宝的 AXML、百度的 Swan Element、字节跳动的 TTML [尽管开发者工具将其称为 Bxml] 和快捷应用的 HTML)的概念都是一样的。与 Vue.js 一样,迷你应用的底层编程概念是 Model-View-ViewModel (MVVM)。

数据绑定

数据绑定对应于 Vue.js 的文本插值

<!-- wxml -->
<view>{{message}}</view>
// page.js
Page({
  data
: {
    message
: "Hello World!",
 
},
});

列表呈现

列表渲染的工作原理与 Vue.js 的 v-for 指令类似。

<!-- wxml -->
<view wx:for="{{array}}">{{item}}</view>
// page.js
Page({
  data
: {
    array
: [1, 2, 3, 4, 5],
 
},
});

按条件呈现

有条件呈现的工作方式与 Vue.js 的 v-if 指令类似。

<!-- wxml -->
<view wx:if="{{view == 'one'}}">One</view>
<view wx:elif="{{view == 'two'}}">Two</view>
<view wx:else="{{view == 'three'}}">Three</view>
// page.js
Page({
  data
: {
    view
: "three",
 
},
});

模板

无需强制克隆 HTML 模板的 content,您可以通过链接到模板定义的 is 属性以声明方式使用 WXML 模板。

<!-- wxml -->
<template name="person">
 
<view>
    First Name: {{firstName}}, Last Name: {{lastName}}
 
</view>
</template>
<template is="person" data="{{...personA}}"></template>
<template is="person" data="{{...personB}}"></template>
<template is="person" data="{{...personC}}"></template>
// page.js
Page({
  data
: {
    personA
: { firstName: "Alice", lastName: "Foo" },
    personB
: { firstName: "Bob", lastName: "Bar" },
    personC
: { firstName: "Charly", lastName: "Baz" },
 
},
});

样式

样式是针对 CSS 的方言而设置。WeChat 的名称为 WXSS。对于支付宝,其 CSS 称为 ACSS;对于百度,其 CSS 称为 CSS;对于字节跳动,其 CSS 称为 TTSS。它们的共同点是它们使用自适应像素扩展 CSS。编写常规 CSS 时,开发者需要转换所有像素单位,以适应宽度和像素宽高比不同的不同移动设备屏幕。TTSS 支持将 rpx 作为其底层,这意味着迷你应用会接管开发者的工作,并根据指定的屏幕宽度 750rpx 代表开发者转换单位。例如,在屏幕宽度为 393px(设备像素比率为 2.75)的 Pixel 3a 手机上,使用 Chrome 开发者工具在实体设备上检查时,响应式 200rpx 会变为 104px(393px / 750rpx * 200rpx ≈ 104px)。在 Android 中,这一概念称为“密度无关像素”。

使用 Chrome 开发者工具检查一个视图(其响应式像素内边距使用 `200rpx` 指定),发现在 Pixel 3a 设备上,该内边距实际上为 `104px`。
使用 Chrome 开发者工具检查 Pixel 3a 设备上的实际内边距。
/* app.wxss */
.container {
 
height: 100%;
 
display: flex;
 
flex-direction: column;
 
align-items: center;
 
justify-content: space-between;
 
padding: 200rpx 0; /* ← responsive pixels */
 
box-sizing: border-box;
}

由于组件(详见后文)不使用 shadow DOM,因此在页面上声明的样式会延伸到所有组件。通常的样式表文件组织方式是为全局样式设置一个根样式表,并为迷你版应用的每个页面创建单独的每个页面样式表。您可以使用 @import 规则导入样式,该规则的行为类似于 @import CSS at-规则。与在 HTML 中一样,样式也可以以内嵌方式声明,包括动态文本插值(请参阅前面)。

<view style="color:{{color}};" />

设计脚本

迷你应用支持 JavaScript 的“安全子集”,其中包括对使用不同语法(提醒 CommonJSRequireJS)的模块的支持。无法通过 eval() 执行 JavaScript 代码,也无法使用 new Function() 创建任何函数。脚本执行上下文在设备上为 V8JavaScriptCore,在模拟器中为 V8 或 NW.js。通常可以使用 ES6 或更高版本语法编码,因为如果 build 目标操作系统是采用旧版 WebView 实现的操作系统(请参阅稍后),特定的开发者工具会自动将代码转译为 ES5。超级应用提供商的文档明确提及,其脚本语言与 JavaScript 不同,不能与之混淆。不过,此陈述主要仅指模块的工作原理,也就是说,它们尚不支持标准 ES 模块

前面所述,迷你应用编程概念是 Model-View-ViewModel (MVVM)。逻辑层和视图层在不同的线程中运行,这意味着界面不会被长时间运行的操作阻塞。从 Web 的角度来看,您可以将其视为在 Web Worker 中运行的脚本。

WeChat 的脚本语言称为 WXS,Alipay 的脚本语言称为 SJS,ByteDance 的脚本语言也称为 SJS。百度在提及自己的 JS 时,会使用 JS 一词。需要使用一种特殊类型的标记(例如微信中的 <wxs>)添加这些脚本。与之相反,快捷应用使用常规 <script> 标记和 ES6 JS 语法。

<wxs module="m1">
  var msg = "hello world";
  module.exports.message = msg;
</wxs>

<view>{{m1.message}}</view>

您还可以通过 src 属性加载模块,或通过 require() 导入模块。

// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
 
return d;
};
module
.exports = {
  FOO
: foo,
  bar
: bar,
};
module
.exports.msg = "some msg";
<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view>{{tools.msg}}</view>
<view>{{tools.bar(tools.FOO)}}</view>
// /pages/logic.wxs
var tools = require("./tools.wxs");

console
.log(tools.FOO);
console
.log(tools.bar("logic.wxs"));
console
.log(tools.msg);

JavaScript 桥接 API

通过连接迷你应用与操作系统的 JavaScript 桥接,可以使用操作系统功能(请参阅使用强大的功能)。它还提供了多种便捷方法。如需了解概览,您可以查看 WeChatAlipayBaiduByteDance快应用的不同 API。

功能检测非常简单,因为所有平台都提供(字面上就是这样称呼的)canIUse() 方法,其名称似乎受到网站 caniuse.com 的启发。例如,ByteDance 的 tt.canIUse() 允许对 API、方法、参数、选项、组件和属性进行支持检查。

// Testing if the `<swiper>` component is supported.
tt
.canIUse("swiper");
// Testing if a particular field is supported.
tt
.canIUse("request.success.data");

更新

迷你应用没有标准化的更新机制(关于可能实现标准化的讨论)。所有迷你应用平台都有一个后端系统,迷你应用开发者可以上传其迷你应用的新版本。然后,超级应用会使用该后端系统检查和下载更新。某些超级应用会完全在后台执行更新,而迷你应用本身无法以任何方式影响更新流程。其他超级应用可以更好地控制迷你应用本身。

下面几段将更详细地介绍 WeChat 的迷你应用更新机制,以此为复杂流程的示例。在以下两种情况下,微信会检查可用更新:

  1. 只要微信在运行,就会定期检查最近用过的微应用是否有更新。如果找到更新,系统会下载该更新,并在用户下次冷启动微应用时同步应用该更新。当用户打开微应用时,如果微应用当前未运行,则会发生冷启动微应用的情况(微信会在微应用在后台运行 5 分钟后强制关闭该微应用)。
  2. WeChat 还会在小程序冷启动时检查更新。对于用户长时间未打开的迷你应用,系统会同步检查并下载更新。在更新下载期间,用户必须等待。下载完成后,系统会应用更新,并打开迷你应用。如果下载失败(例如,由于网络连接不佳),系统仍会打开迷你应用。对于用户最近打开的迷你应用,任何可能的更新都会在后台异步下载,并将在用户下次冷启动迷你应用时应用。

迷你应用可以使用 UpdateManager API 选择接受更早的更新。它提供以下功能:

  • 在检查更新时通知迷你应用。 (onCheckForUpdate)
  • 当有更新已下载完毕且可用时,通知迷你版应用。 (onUpdateReady)
  • 在无法下载更新时通知迷你应用。 (onUpdateFailed)
  • 允许迷你应用强制安装可用更新,这将重启应用。 (applyUpdate)

WeChat 还在其后端系统中为迷你应用开发者提供了其他更新自定义选项: 1. 其中一个选项允许开发者为已安装特定最低版本迷你应用的用户停用同步更新,并强制执行异步更新。2. 另一种方法允许开发者设置迷你应用的最低版本要求。这样一来,如果从低于最低版本要求的版本进行异步更新,系统会在应用更新后强制重新加载迷你应用。如果更新下载失败,它还会阻止打开旧版迷你应用。

致谢

本文由 Joe MedleyKayce BasquesMilica MihajlijaAlan Kent 和 Keith Gu 审核。