Языки разметки
Как отмечалось ранее, мини-приложения пишутся с использованием диалектов 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!",
},
});
Рендеринг списка
Рендеринг списков работает как директива Vue.js v-for
.
<!-- 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 DevTools (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
, которое ведет себя как правило CSS @import
. Как и в HTML, стили также могут быть объявлены встроенными, включая динамическую интерполяцию текста (см. выше ).
<view style="color:{{color}};" />
Сценарии
Мини-приложения поддерживают «безопасное подмножество» JavaScript, которое включает поддержку модулей, использующих различные синтаксисы, напоминающие CommonJS или RequireJS . Код JavaScript не может быть выполнен с помощью eval()
и никакие функции не могут быть созданы с помощью new Function()
. Контекстом выполнения сценария является V8 или JavaScriptCore на устройствах и V8 или NW.js в симуляторе. Кодирование с использованием синтаксиса ES6 или более нового обычно возможно, поскольку определенные DevTools автоматически переносят код в 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 работает. Если обновление обнаружено, оно загружается и синхронно применяется при следующем холодном запуске мини-приложения пользователем. Холодный запуск мини-приложений происходит, когда мини-приложение в данный момент не запущено, когда пользователь его открыл (WeChat принудительно закрывает мини-приложения после нахождения в фоновом режиме в течение 5 минут).
- WeChat также проверяет наличие обновлений при холодном запуске мини-приложения. Для мини-приложений, которые пользователь долгое время не открывал, обновление проверяется и загружается синхронно. Пока обновление загружается, пользователю приходится ждать. После завершения загрузки обновление будет применено и откроется мини-приложение. Если загрузка не удалась, например, из-за плохого сетевого подключения, мини-приложение все равно откроется. Для мини-приложений, которые пользователь недавно открывал, любое потенциальное обновление загружается асинхронно в фоновом режиме и будет применено при следующем холодном запуске мини-приложения пользователем.
Мини-приложения могут подписаться на более ранние обновления с помощью API UpdateManager
. Он обеспечивает следующий функционал:
- Уведомляет мини-приложение о проверке обновлений. (
onCheckForUpdate
) - Уведомляет мини-приложение, когда обновление загружено и доступно. (
onUpdateReady
) - Уведомляет мини-приложение, если обновление не удалось загрузить. (
onUpdateFailed
) - Позволяет мини-приложению принудительно установить доступное обновление, после чего приложение перезапустится. (
applyUpdate
)
WeChat также предоставляет дополнительные возможности настройки обновлений для разработчиков мини-приложений в своей внутренней системе: 1. Один из вариантов позволяет разработчикам отказаться от синхронных обновлений для пользователей, у которых уже установлена определенная минимальная версия мини-приложения, и вместо этого принудительно устанавливать обновления. быть асинхронным. 2. Другой вариант позволяет разработчикам установить минимально необходимую версию своего мини-приложения. Это приведет к асинхронным обновлениям версии ниже минимально необходимой версии и принудительной перезагрузке мини-приложения после применения обновления. Он также заблокирует открытие более старой версии мини-приложения, если загрузка обновления не удалась.
Благодарности
Рецензии на эту статью написали Джо Медли , Кейси Баскис , Милица Михайлия , Алан Кент и Кейт Гу.