Языки разметки
Как уже отмечалось ранее, вместо обычного HTML, мини-приложения пишутся с использованием диалектов HTML. Если вы когда-либо работали с интерполяцией текста и директивами в Vue.js , вы сразу почувствуете себя как дома, но подобные концепции существовали задолго до этого в преобразованиях XML ( XSLT ). Ниже вы можете увидеть примеры кода из WXML WeChat, но концепция одинакова для всех платформ мини-приложений, а именно AXML Alipay, Swan Element Baidu, TTML ByteDance (несмотря на то, что в DevTools он называется Bxml) и HTML Quick App. Как и в Vue.js, в основе программирования мини-приложений лежит модель «модель-представление-модель представления » (MVVM).
Привязка данных
Привязка данных соответствует интерполяции текста в Vue.js.
<!-- wxml -->
<view>{{message}}</view>
// page.js
Page({
data: {
message: "Hello World!",
},
});
Отображение списка
Рендеринг списков работает аналогично директиве v-for в Vue.js.
<!-- wxml -->
<view wx:for="{{array}}">{{item}}</view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5],
},
});
Условная отрисовка
Условный рендеринг работает аналогично директиве v-if в Vue.js.
<!-- 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",
},
});
Шаблоны
Вместо обязательного клонирования content HTML-шаблона , шаблоны WXML можно использовать декларативно с помощью атрибута is , который ссылается на определение шаблона.
<!-- 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 . У Alipay он называется ACSS , у Baidu — просто CSS , а у ByteDance — TTSS . Общим для них является то, что они расширяют CSS адаптивными пикселями. При написании обычного CSS разработчикам необходимо преобразовывать все пиксельные единицы, чтобы адаптироваться к различным экранам мобильных устройств с разной шириной и соотношением сторон. TTSS поддерживает единицу rpx в качестве базового слоя, что означает, что мини-приложение берет на себя эту задачу и преобразует единицы от имени разработчика, исходя из заданной ширины экрана в 750rpx . Например, на телефоне Pixel 3a с шириной экрана 393px (и коэффициентом пикселизации устройства 2.75 ) адаптивные 200rpx становятся 104px на реальном устройстве при проверке с помощью инструментов разработчика Chrome (393 пикселя / 750 пикселей * 200 пикселей ≈ 104 пикселя). В Android это же понятие называется пикселем, не зависящим от плотности .

/* 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;
}
Поскольку компоненты (см. далее ) не используют теневой DOM, стили, объявленные на странице, распространяются на все компоненты. Обычно файлы таблиц стилей организованы следующим образом: одна корневая таблица стилей для глобальных стилей и отдельные таблицы стилей для каждой страницы мини-приложения. Стили можно импортировать с помощью правила @import , которое работает аналогично правилу @import для CSS. Как и в HTML, стили также можно объявлять встроенно, включая динамическую интерполяцию текста (см. выше ).
<view style="color:{{color}};" />
Скриптинг
Мини-приложения поддерживают «безопасное подмножество» JavaScript, которое включает поддержку модулей с различным синтаксисом, напоминающим CommonJS или RequireJS . Код JavaScript нельзя выполнить через eval() , и нельзя создавать функции с помощью new Function() . Контекст выполнения скриптов — V8 или JavaScriptCore на устройствах и V8 или NW.js в симуляторе. Кодирование с использованием синтаксиса ES6 или более новых версий обычно возможно, поскольку соответствующие инструменты разработчика автоматически транспилируют код в ES5, если целевая операционная система имеет более старую реализацию WebView (см. далее ). В документации поставщиков суперприложений явно указано, что их языки сценариев не следует путать с JavaScript и они отличаются от него. Однако это утверждение относится в основном только к тому, как работают модули, то есть они пока не поддерживают стандартные модули ES .
Как уже упоминалось, концепция программирования мини-приложений основана на модели «модель-представление-представление-модель » (MVVM). Логический слой и слой представления работают в разных потоках, что означает, что пользовательский интерфейс не блокируется длительными операциями. В веб-терминах это можно представить как скрипты, работающие в Web Worker .
Язык сценариев WeChat называется WXS , Alipay — SJS , ByteDance — также SJS . Baidu использует термин JS , когда говорит о своих скриптах. Эти скрипты необходимо включать с помощью специального тега, например, <wxs> в WeChat. В отличие от них, Quick App использует обычные теги <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);
API моста JavaScript
Мост JavaScript, соединяющий мини-приложения с операционной системой, позволяет использовать возможности ОС (см. раздел «Доступ к мощным функциям» ). Он также предлагает ряд удобных способов. Для общего обзора вы можете ознакомиться с различными API WeChat , Alipay , Baidu , ByteDance и Quick App .
Обнаружение функций не представляет сложности, поскольку все платформы предоставляют метод canIUse() (буквально называемый так), название которого, кажется, вдохновлено сайтом caniuse.com . Например, tt.canIUse() от ByteDance позволяет проверять поддержку API, методов, параметров, опций, компонентов и атрибутов.
// Testing if the `<swiper>` component is supported.
tt.canIUse("swiper");
// Testing if a particular field is supported.
tt.canIUse("request.success.data");
Обновления
Мини-приложения не имеют стандартизированного механизма обновления ( обсуждение потенциальной стандартизации ). Все платформы для мини-приложений имеют бэкэнд-систему, которая позволяет разработчикам мини-приложений загружать новые версии своих мини-приложений. Затем суперприложение использует эту бэкэнд-систему для проверки и загрузки обновлений. Некоторые суперприложения выполняют обновления полностью в фоновом режиме, без возможности для самого мини-приложения влиять на процесс обновления. Другие суперприложения предоставляют больший контроль самим мини-приложениям.
В качестве примера сложного процесса в следующих параграфах более подробно описан механизм обновления мини-приложений в WeChat . WeChat проверяет наличие доступных обновлений в следующих двух сценариях:
- Пока приложение работает, WeChat регулярно проверяет наличие обновлений для недавно использованных мини-приложений. Если обновление найдено, оно загружается и синхронно применяется при следующем запуске мини-приложения пользователем. Запуск мини-приложения происходит, когда оно не было запущено в момент открытия пользователем (WeChat принудительно закрывает мини-приложения после 5 минут работы в фоновом режиме).
- WeChat также проверяет наличие обновлений при «холодном» запуске мини-приложения. Для мини-приложений, которые пользователь давно не открывал, обновление проверяется и загружается синхронно. Пока загружается обновление, пользователю приходится ждать. После завершения загрузки обновление применяется, и мини-приложение открывается. Если загрузка не удается, например, из-за плохого сетевого соединения, мини-приложение открывается независимо от этого. Для мини-приложений, которые пользователь открывал недавно, любое потенциальное обновление загружается асинхронно в фоновом режиме и будет применено при следующем «холодном» запуске мини-приложения.
Мини-приложения могут подключаться к более ранним обновлениям, используя API UpdateManager . Он предоставляет следующие возможности:
- Уведомляет мини-приложение о проверке наличия обновлений. (
onCheckForUpdate) - Уведомляет мини-приложение о загрузке и доступности обновления. (
onUpdateReady) - Уведомляет мини-приложение в случае, если обновление не удалось загрузить. (
onUpdateFailed) - Позволяет мини-приложению принудительно установить доступное обновление, что приведет к перезапуску приложения. (
applyUpdate)
WeChat также предоставляет разработчикам мини-приложений дополнительные параметры настройки обновлений в своей внутренней системе: 1. Один из вариантов позволяет разработчикам отказаться от синхронных обновлений для пользователей, у которых уже установлена определенная минимальная версия мини-приложения, и вместо этого принудительно запускать асинхронные обновления. 2. Другой вариант позволяет разработчикам установить минимально необходимую версию своего мини-приложения. Это приведет к тому, что асинхронные обновления с версией ниже минимально необходимой будут принудительно перезагружать мини-приложение после применения обновления. Это также заблокирует открытие более старой версии мини-приложения, если загрузка обновления не удастся.
Благодарности
Данная статья была рецензирована Джо Медли , Кейси Баскесом , Милицей Михайловией , Аланом Кентом и Китом Гу.