Đánh dấu, định kiểu, viết tập lệnh và cập nhật ứng dụng nhỏ

Ngôn ngữ đánh dấu

Như đã nêu trước đó, thay vì HTML thuần tuý, ứng dụng mini được viết bằng các phương ngữ HTML. Nếu từng xử lý các lệnh và nội dung nội suy văn bản Vue.js, bạn sẽ thấy quen thuộc ngay lập tức. Tuy nhiên, các khái niệm tương tự đã tồn tại từ lâu trong các phép biến đổi XML (XSLT). Dưới đây, bạn có thể xem các mã mẫu từ WXML của WeChat, nhưng khái niệm này giống nhau đối với tất cả nền tảng ứng dụng nhỏ, cụ thể là AXML của Alipay, Swan Element của Baidu, TTML của ByteDance (mặc dù DevTools gọi là Bxml) và HTML của Quick App. Giống như với Vue.js, khái niệm lập trình ứng dụng nhỏ cơ bản là mô hình-thành phần hiển thị-thành phần hiển thị (MVVM).

Liên kết dữ liệu

Liên kết dữ liệu tương ứng với tính năng nội suy văn bản của Vue.js.

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

Kết xuất danh sách

Tính năng kết xuất danh sách hoạt động như lệnh v-for của Vue.js.

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

Kết xuất có điều kiện

Tính năng hiển thị có điều kiện hoạt động giống như lệnh v-if của 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",
  },
});

Mẫu

Thay vì bắt buộc sao chép content của mẫu HTML, bạn có thể sử dụng mẫu WXML theo cách khai báo thông qua thuộc tính is liên kết đến một định nghĩa mẫu.

<!-- 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" },
  },
});

Định kiểu

Việc tạo kiểu diễn ra với các phương ngữ CSS. WeChat có tên là WXSS. Đối với Alipay, phương thức của họ được gọi là ACSS, đơn giản là CSS của Baidu, còn đối với ByteDance, phương ngữ của họ được gọi là TTSS. Điểm chung của các thuộc tính này là chúng mở rộng CSS bằng các pixel thích ứng. Khi viết CSS thông thường, nhà phát triển cần chuyển đổi tất cả các đơn vị pixel để thích ứng với các màn hình thiết bị di động khác nhau có chiều rộng và tỷ lệ pixel khác nhau. TTSS hỗ trợ đơn vị rpx làm lớp cơ bản, nghĩa là ứng dụng mini sẽ tiếp nhận công việc của nhà phát triển và thay mặt họ chuyển đổi các đơn vị, dựa trên chiều rộng màn hình được chỉ định là 750rpx. Ví dụ: trên điện thoại Pixel 3a có chiều rộng màn hình là 393px (và tỷ lệ pixel của thiết bị là 2.75), 200rpx thích ứng sẽ trở thành 104px trên thiết bị thực khi được kiểm tra bằng Công cụ của Chrome cho nhà phát triển (393px / 750rpx * 200rpx ≈ 104px). Trong Android, khái niệm tương tự được gọi là pixel không phụ thuộc vào mật độ.

Kiểm tra một khung hiển thị bằng Công cụ của Chrome cho nhà phát triển có khoảng đệm pixel thích ứng được chỉ định bằng &quot;200rpx&quot; cho thấy thực tế là &quot;104px&quot; trên thiết bị Pixel 3a.
Kiểm tra khoảng đệm thực tế trên thiết bị Pixel 3a bằng Công cụ của Chrome cho nhà phát triển.
/* 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;
}

Vì các thành phần (xem sau) không sử dụng shadow DOM, nên các kiểu được khai báo trên một trang sẽ truy cập vào tất cả các thành phần. Cách sắp xếp tệp biểu định kiểu phổ biến là có một tệp định kiểu gốc cho kiểu chung và biểu định kiểu riêng lẻ cho mỗi trang dành riêng cho từng trang của ứng dụng nhỏ. Bạn có thể nhập kiểu bằng quy tắc @import hoạt động giống như quy tắc tại phần CSS @import. Giống như trong HTML, bạn cũng có thể khai báo các kiểu cùng dòng, bao gồm cả nội suy văn bản động (xem trước).

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

Lên nội dung

Ứng dụng mini hỗ trợ một "nhóm con an toàn" của JavaScript, bao gồm cả việc hỗ trợ các mô-đun sử dụng nhiều cú pháp gợi nhớ đến CommonJS hoặc RequireJS. Bạn không thể thực thi mã JavaScript qua eval() và không thể tạo hàm bằng new Function(). Ngữ cảnh thực thi tập lệnh là V8 hoặc JavaScriptCore trên thiết bị và V8 hoặc NW.js trong trình mô phỏng. Bạn thường có thể lập trình bằng cú pháp ES6 trở lên, vì DevTools cụ thể sẽ tự động biên dịch mã sang ES5 nếu mục tiêu bản dựng là một hệ điều hành có cách triển khai WebView cũ (xem phần sau này). Tài liệu về các nhà cung cấp ứng dụng cao cấp đề cập rõ ràng rằng ngôn ngữ tập lệnh của họ không bị nhầm lẫn và khác với JavaScript. Tuy nhiên, câu lệnh này chủ yếu chỉ đề cập đến cách hoạt động của các mô-đun, tức là các mô-đun này chưa hỗ trợ Mô-đun ES tiêu chuẩn.

Như đã đề cập trước đây, khái niệm lập trình ứng dụng nhỏ là model-view-viewmodel (MVVM). Lớp logic và lớp thành phần hiển thị chạy trên các luồng khác nhau, nghĩa là giao diện người dùng không bị các thao tác chạy trong thời gian dài chặn. Trong thuật ngữ web, bạn có thể coi các tập lệnh chạy trong một Trình chạy web.

Ngôn ngữ tập lệnh của WeChat được gọi là WXS, SJS của Alipay, SJS của ByteDance tương tự. Baidu nói đến JS khi nhắc đến mã của họ. Bạn cần đưa các tập lệnh này vào bằng một loại thẻ đặc biệt, ví dụ: <wxs> trong WeChat. Ngược lại, Ứng dụng nhanh sử dụng các thẻ <script> thông thường và cú pháp JS ES6.

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

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

Bạn cũng có thể tải mô-đun thông qua thuộc tính src hoặc nhập mô-đun thông qua 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 cầu JavaScript

Cầu JavaScript kết nối các ứng dụng mini với hệ điều hành cho phép sử dụng các chức năng của hệ điều hành (xem phần Truy cập vào các tính năng mạnh mẽ). Thư viện này cũng cung cấp một số phương thức tiện lợi. Để biết thông tin tổng quan, bạn có thể xem các API khác nhau của WeChat, Alipay, Baidu, ByteDanceQuick App.

Việc phát hiện tính năng rất đơn giản, vì tất cả các nền tảng đều cung cấp phương thức canIUse() (được gọi theo nghĩa đen như vậy) có tên dường như được lấy cảm hứng từ trang web caniuse.com. Ví dụ: tt.canIUse() của ByteDance cho phép kiểm tra tính năng hỗ trợ cho API, phương thức, tham số, tuỳ chọn, thành phần và thuộc tính.

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

Nội dung cập nhật

Ứng dụng mini không có cơ chế cập nhật được chuẩn hoá (cuộc thảo luận về khả năng chuẩn hoá). Tất cả nền tảng ứng dụng mini đều có hệ thống phụ trợ, cho phép nhà phát triển ứng dụng mini tải các phiên bản mới của ứng dụng mini lên. Sau đó, một ứng dụng siêu cấp sẽ sử dụng hệ thống phụ trợ đó để kiểm tra và tải các bản cập nhật xuống. Một số siêu ứng dụng thực hiện cập nhật hoàn toàn ở chế độ nền mà không có cách nào để ứng dụng nhỏ tác động đến luồng cập nhật. Các ứng dụng siêu lớn khác cho phép các ứng dụng nhỏ có nhiều quyền kiểm soát hơn.

Ví dụ về một quy trình phức tạp, các đoạn sau đây mô tả chi tiết hơn về cơ chế cập nhật của WeChat cho ứng dụng mini. WeChat kiểm tra các bản cập nhật có sẵn trong hai trường hợp sau:

  1. WeChat sẽ thường xuyên kiểm tra để tìm bản cập nhật của các ứng dụng nhỏ được sử dụng gần đây, miễn là WeChat vẫn đang chạy. Nếu tìm thấy bản cập nhật, bản cập nhật sẽ được tải xuống và đồng bộ áp dụng vào lần tiếp theo người dùng khởi động nguội ứng dụng nhỏ. Quá trình khởi động nguội ứng dụng nhỏ xảy ra khi ứng dụng nhỏ hiện không chạy khi người dùng mở ứng dụng đó (WeChat buộc đóng ứng dụng nhỏ sau khi chạy ở chế độ nền trong 5 phút).
  2. WeChat cũng kiểm tra bản cập nhật khi một ứng dụng nhỏ khởi động nguội. Đối với các ứng dụng nhỏ mà người dùng chưa mở trong một thời gian dài, bản cập nhật sẽ được kiểm tra và tải xuống đồng bộ. Trong khi tải bản cập nhật xuống, người dùng phải đợi. Sau khi tải xuống xong, bản cập nhật sẽ được áp dụng và ứng dụng thu nhỏ sẽ mở ra. Nếu quá trình tải xuống không thành công, chẳng hạn như do kết nối mạng kém, thì ứng dụng thu nhỏ sẽ mở ra bất kể điều gì. Đối với các ứng dụng nhỏ mà người dùng đã mở gần đây, mọi bản cập nhật tiềm năng sẽ được tải xuống không đồng bộ ở chế độ nền và sẽ được áp dụng vào lần tiếp theo người dùng khởi động nguội ứng dụng nhỏ.

Ứng dụng mini có thể chọn sử dụng các bản cập nhật trước đó bằng API UpdateManager. Thư viện này cung cấp chức năng sau:

  • Thông báo cho ứng dụng thu nhỏ khi có bản cập nhật. (onCheckForUpdate)
  • Thông báo cho ứng dụng thu nhỏ khi có bản cập nhật đã tải xuống và có sẵn. (onUpdateReady)
  • Thông báo cho ứng dụng thu nhỏ khi không thể tải bản cập nhật xuống. (onUpdateFailed)
  • Cho phép ứng dụng thu nhỏ buộc cài đặt bản cập nhật hiện có. Thao tác này sẽ khởi động lại ứng dụng. (applyUpdate)

WeChat cũng cung cấp các tuỳ chọn tuỳ chỉnh bản cập nhật bổ sung cho nhà phát triển ứng dụng mini trong hệ thống phụ trợ: 1. Một tuỳ chọn cho phép nhà phát triển chọn không sử dụng tính năng cập nhật đồng bộ cho những người dùng đã cài đặt một phiên bản tối thiểu nhất định của ứng dụng mini, thay vào đó buộc các bản cập nhật phải không đồng bộ. 2. Một tuỳ chọn khác cho phép nhà phát triển đặt một phiên bản tối thiểu bắt buộc của ứng dụng nhỏ. Thao tác này sẽ khiến các bản cập nhật không đồng bộ từ phiên bản thấp hơn phiên bản tối thiểu bắt buộc sẽ buộc tải lại ứng dụng nhỏ sau khi áp dụng bản cập nhật. Tính năng này cũng sẽ chặn việc mở phiên bản cũ của ứng dụng mini nếu quá trình tải bản cập nhật xuống không thành công.

Lời cảm ơn

Bài viết này đã được Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent và Keith Gu xem xét.