Ngôn ngữ đánh dấu
Như đã nêu trước đó, thay vì bằng HTML thuần tuý, các ứng dụng nhỏ được viết bằng các phương ngữ HTML. Nếu bạn đã từng xử lý nội suy văn bản và lệnh Vue.js, bạn sẽ cảm thấy gần như ngay lập tức, nhưng các khái niệm tương tự đã tồn tại trước đó trong phiên bản Chuyể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 là giống nhau cho tất cả các nền tảng ứng dụng nhỏ của Công cụ cho nhà phát triển, cụ thể là AXML của Alipay, Phần tử sau của Baidu, TTML của ByteDance (mặc dù gọi là Bxml) và HTML của ứng dụng nhanh. Cũng giống như Vue.js, khái niệm lập trình ứng dụng nhỏ cơ bản là model-view-viewmodel (MVVM).
Liên kết dữ liệu
Việc 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!",
},
});
Hiển thị danh sách
Tính năng hiển thị danh sách hoạt động giố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],
},
});
Hiển thị có điều kiện
Phương thức kết xuất 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ì yêu cầu bản sao của content
của một mẫu HTML bắt buộc, 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 đị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 phương ngữ của CSS. WeChat có tên là WXSS.
Đối với Alipay, 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 hai công cụ này là mở rộng CSS bằng 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ả đơn vị pixel để thích ứng với nhiều màn hình của thiết bị di động 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 nhỏ sẽ tiếp quản công việc của nhà phát triển và thay mặt nhà phát triển chuyển đổi các đơn vị đó dựa trên chiều rộng màn hình 750rpx
được chỉ định. 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 "200rpx" cho thấy khung hiển thị đó thực sự là "104px" trên thiết bị Pixel 3a.](https://web.dev/static/articles/mini-apps/mini-app-markup-styling-and-scripting/image/inspecting-view-chrome.png?authuser=5&hl=vi)
/* 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 DOM bóng, nên các kiểu được khai báo trên trang sẽ chuyển đến 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 biểu định kiểu gốc cho kiểu chung và các biểu định kiểu mỗi trang riêng lẻ cho từng trang của ứng dụng nhỏ. Bạn có thể nhập các kiểu bằng quy tắc @import
hoạt động giống như quy tắc CSS @import
ở phần đầu. Giống như trong HTML, kiểu cũng có thể được khai báo 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
Các ứng dụng nhỏ hỗ trợ một "tập hợp con an toàn" của JavaScript, trong đó hỗ trợ các mô-đun sử dụng các cú pháp khác nhau nhắc nhở CommonJS hoặc RequireJS.
Bạn không thể thực thi mã JavaScript qua eval()
và không thể tạo hàm nào bằng new Function()
. Ngữ cảnh thực thi tập lệnh là V8 hoặc JavaScriptCore trên các 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 với cú pháp ES6 hoặc mới hơn, vì Công cụ cho nhà phát triển cụ thể tự động dịch mã sang ES5 nếu mục tiêu bản dựng là một hệ điều hành có phương thức triển khai WebView cũ (xem sau). Tài liệu về các nhà cung cấp ứng dụng cấp cao đề cập rõ ràng rằng ngôn ngữ tập lệnh của họ không nên bị nhầm lẫn và khác với JavaScript. Tuy nhiên, câu lệnh này chủ yếu đề cập đến cách hoạt động của các mô-đun, tức là các mô-đun 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 thu nhỏ là model-view-viewmodel (MVVM). Lớp logic và lớp khung 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 diễn ra trong thời gian dài chặn lại. Trong thuật ngữ web, bạn có thể nghĩ đến các tập lệnh chạy trong Web Worker.
Ngôn ngữ tập lệnh của WeChat có tên là WXS, SJS của Alipay, SJS của ByteDance.
Baidu nói đến JS khi đề cập đến phần tử của họ. Các tập lệnh này cần được đưa 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 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>
Các mô-đun cũng có thể được tải thông qua thuộc tính src
hoặc được nhập 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 nối JavaScript
Cầu JavaScript kết nối các ứng dụng nhỏ với hệ điều hành giúp bạn có thể sử dụng các tính năng của hệ điều hành (xem bài viết Truy cập vào các tính năng mạnh mẽ. Lớp này cũng cung cấp một số phương thức thuận tiện. Để biết thông tin tổng quan, bạn có thể xem các API khác nhau của WeChat, Alipay, Baidu, ByteDance và Quick 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 một phương thức canIUse()
(được gọi theo nghĩa đen là tên này) có tên lấy cảm hứng từ trang web caniuse.com. Ví dụ: tt.canIUse()
của ByteDance cho phép kiểm tra 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");
Các bản cập nhật
Các ứng dụng nhỏ không có cơ chế cập nhật chuẩn (thảo luận về việc tiêu chuẩn hoá tiềm năng). Tất cả các nền tảng ứng dụng nhỏ đều có hệ thống phụ trợ, cho phép nhà phát triển ứng dụng nhỏ tải phiên bản mới của ứng dụng nhỏ lên. Sau đó, một ứng dụng lớn 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 việc cập nhật hoàn toàn ở chế độ nền mà không có cách nào để ứng dụng thu nhỏ tác động đến quy trình cập nhật. Các siêu ứng dụng khác trao nhiều quyền kiểm soát hơn đối với chính các ứng dụng thu nhỏ.
Các đoạn sau đây là một ví dụ về một quy trình tinh vi, mô tả chi tiết hơn về cơ chế cập nhật của WeChat cho các ứng dụng nhỏ. WeChat kiểm tra các bản cập nhật có sẵn trong hai tình huống sau:
- WeChat sẽ thường xuyên kiểm tra 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 đ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à áp dụng đồng bộ 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 một ứng dụng nhỏ sẽ diễn 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 các ứng dụng nhỏ sau khi chạy ở chế độ nền trong 5 phút).
- WeChat cũng kiểm tra bản cập nhật khi một ứng dụng nhỏ được khởi động nguội. Đối với các ứng dụng nhỏ mà người dùng không 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 bản cập nhật đang tải xuống, người dùng phải đợi. Sau khi quá trình tải xuống hoàn tất, bản cập nhật sẽ được áp dụng và ứng dụng thu nhỏ sẽ mở ra. Nếu tải xuống không thành công (chẳng hạn như do kết nối mạng kém), ứng dụng thu nhỏ sẽ mở ra bất kể ứng dụng đó. Đố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 đều được tải xuống không đồng bộ trong 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ỏ.
Các ứng dụng nhỏ có thể chọn nhận bản cập nhật trước đó bằng cách sử dụng API UpdateManager
. Mã này cung cấp chức năng sau:
- Thông báo cho ứng dụng nhỏ khi kiểm tra bản cập nhật.
(
onCheckForUpdate
) - Thông báo cho ứng dụng nhỏ khi đã tải xuống và có bản cập nhật.
(
onUpdateReady
) - Thông báo cho ứng dụng 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 một bản cập nhật có sẵn. Bản cập nhật 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 các nhà phát triển ứng dụng nhỏ trong hệ thống phụ trợ: 1. Một lựa chọn cho phép nhà phát triển chọn không sử dụng bản cập nhật đồng bộ đối với 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 mà 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 thiết lập phiên bản tối thiểu bắt buộc của ứng dụng nhỏ. Điều 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 phải tải lại ứng dụng nhỏ sau khi áp dụng bản cập nhật. Thao tác này cũng sẽ chặn việc mở phiên bản cũ hơn của ứng dụng thu nhỏ nếu bạn không tải được bản cập nhật xuống.
Xác nhận
Bài viết này được Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent và Keith Gu xem xét.