Разметка мини-приложений, стилизация, создание сценариев и обновление.

Как отмечалось ранее, мини-приложения пишутся с использованием диалектов 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 та же концепция называется пикселем, независимым от плотности .

Проверка представления с помощью Chrome DevTools, в котором адаптивное заполнение пикселей было указано с помощью `200rpx`, показывает, что на самом деле на устройстве Pixel 3a оно составляет `104px`.
Проверка фактического заполнения на устройстве Pixel 3a с помощью Chrome DevTools.
/* 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 , SJS Alipay, 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 проверяет наличие доступных обновлений в следующих двух сценариях:

  1. WeChat будет регулярно проверять наличие обновлений недавно использованных мини-приложений, пока WeChat работает. Если обновление обнаружено, оно загружается и синхронно применяется при следующем холодном запуске мини-приложения пользователем. Холодный запуск мини-приложений происходит, когда мини-приложение в данный момент не работало, когда пользователь его открыл (WeChat принудительно закрывает мини-приложения после 5 минут работы в фоновом режиме).
  2. WeChat также проверяет наличие обновлений при холодном запуске мини-приложения. Для мини-приложений, которые пользователь долгое время не открывал, обновление проверяется и загружается синхронно. Пока обновление загружается, пользователю приходится ждать. После завершения загрузки обновление будет применено и откроется мини-приложение. Если загрузка не удалась, например, из-за плохого сетевого подключения, мини-приложение все равно откроется. Для мини-приложений, которые пользователь недавно открывал, любое потенциальное обновление загружается асинхронно в фоновом режиме и будет применено при следующем холодном запуске мини-приложения пользователем.

Мини-приложения могут подписаться на более ранние обновления с помощью API UpdateManager . Он обеспечивает следующий функционал:

  • Уведомляет мини-приложение о проверке обновлений. ( onCheckForUpdate )
  • Уведомляет мини-приложение, когда обновление загружено и доступно. ( onUpdateReady )
  • Уведомляет мини-приложение, если обновление не удалось загрузить. ( onUpdateFailed )
  • Позволяет мини-приложению принудительно установить доступное обновление, что приведет к перезапуску приложения. ( applyUpdate )

WeChat также предоставляет дополнительные возможности настройки обновлений для разработчиков мини-приложений в своей внутренней системе: 1. Один из вариантов позволяет разработчикам отказаться от синхронных обновлений для пользователей, у которых уже установлена ​​определенная минимальная версия мини-приложения, и вместо этого принудительно устанавливать обновления. быть асинхронным. 2. Другой вариант позволяет разработчикам установить минимально необходимую версию своего мини-приложения. Это приведет к асинхронным обновлениям версии ниже минимально необходимой версии и принудительной перезагрузке мини-приложения после применения обновления. Он также заблокирует открытие более старой версии мини-приложения, если загрузка обновления не удалась.

Благодарности

Рецензии на эту статью написали Джо Медли , Кейси Баскис , Милица Михайлия , Алан Кент и Кейт Гу.