ウェブ コンポーネント
ウェブ コンポーネントは、デベロッパーがコンポーネントを組み合わせて、その上に優れたアプリを構築できるようにするという約束から始まりました。このようなアトミック コンポーネントの例としては、GitHub の time-elements、Stefan Judis の web-vitals-element、Google の ダークモード切り替え などがあります。ただし、完全なデザイン システムに関しては、同じベンダーのコンポーネントのまとまりのあるセットに依存することを好む傾向があることがわかりました。例としては、SAP の UI5 Web Components、Polymer Elements、Vaadin の要素、Microsoft の FAST、Material Web Components、AMP コンポーネントなどがあります。この記事の範囲外のさまざまな要因により、多くのデベロッパーが React、Vue.js、Ember.js などのフレームワークに集まっています。スーパーアプリ プロバイダは、デベロッパーがこれらのオプションから自由に選択できるようにする(または、視点によっては、テクノロジーの選択を強制する)のではなく、デベロッパーが使用しなければならないコンポーネントのセットを普遍的に提供しています。
ミニアプリのコンポーネント
これらのコンポーネントは、上記のコンポーネント ライブラリと同様に考えることができます。利用可能なコンポーネントの概要については、WeChat のコンポーネント ライブラリ、ByteDance のコンポーネント、Alipay のコンポーネント、Baidu、クイック アプリのコンポーネントを参照してください。
以前に説明したように、たとえば WeChat の <image> は内部的にはウェブ コンポーネントですが、これらのコンポーネントがすべて技術的にウェブ コンポーネントであるわけではありません。<map> や <video> などの一部のコンポーネントは、WebView の上に重ねられる OS 組み込みコンポーネントとしてレンダリングされます。デベロッパーにはこの実装の詳細は明らかにされず、他のコンポーネントと同様にプログラミングされます。
詳細は異なりますが、プログラミングの全体的なコンセプトは、すべてのスーパーアプリ プロバイダで同じです。重要なコンセプトは、マークアップ言語で説明したデータ バインディングです。通常、コンポーネントは機能ごとにグループ化されているため、作業に適したコンポーネントを簡単に見つけることができます。以下は、Alipay の分類の例です。他のベンダーのコンポーネント グループ化と似ています。
- コンテナを表示する
viewswiperscroll-viewcover-viewcover-imagemovable-viewmovable-area
- 基本的なコンテンツ
texticonprogressrich-text
- フォーム コンポーネント
buttonformlabelinputtextarearadioradio-groupcheckboxcheckbox-groupswitchsliderpicker-viewpicker
- ナビゲーション
navigator
- メディア コンポーネント
imagevideo
- キャンバス
canvas
- 地図
map
- オープン コンポーネント
web-viewlifestylecontact-button
- ユーザー補助
aria-component
以下は、index.js で提供される画像データ配列をループ処理する a:for ディレクティブ(リストのレンダリングを参照)で使用される Alipay の <image> です。
/* index.js */
Page({
data: {
array: [
{
mode: "scaleToFill",
text: "scaleToFill",
},
{
mode: "aspectFit",
text: "aspectFit",
},
],
src: "https://images.example.com/sample.png",
},
imageError(e) {
console.log("image", e.detail.errMsg);
},
onTap(e) {
console.log("image tap", e);
},
imageLoad(e) {
console.log("image", e);
},
});
<!-- index.axml -->
<view class="page">
<view class="page-section" a:for="{{array}}" a:for-item="item">
<view class="page-section-demo" onTap="onTap">
<image
class="image"
mode="{{item.mode}}"
onTap="onTap"
onError="imageError"
onLoad="imageLoad"
src="{{src}}"
lazy-load="true"
default-source="https://images.example.com/loading.png"
/>
</view>
</view>
</view>
item.mode の mode 属性へのデータ バインディング、src の src 属性へのデータ バインディング、3 つのイベント ハンドラ onTap、onError、onLoad の同じ名前の関数へのデータ バインディングに注目してください。前述のように、<image> タグは内部的に <div> に変換され、画像の最終的なサイズのプレースホルダ、オプションの遅延読み込み、デフォルトのソースなどが含まれます。
コンポーネントで使用可能な構成オプションは、すべてドキュメントに記載されています。ドキュメントに埋め込まれたシミュレータ付きのコンポーネント プレビューにより、コードをすぐに実感できます。
各コンポーネントには、Alipay アプリでスキャンできる QR コードもあります。この QR コードをスキャンすると、自己完結型の最小限の例でコンポーネントの例が開きます。
<image> コンポーネントをプレビューした様子。
デベロッパーは、独自の URI スキーム antdevtool-tiny:// を利用して、ドキュメントから Alipay DevTools IDE に直接移動できます。これにより、ドキュメントからインポート対象のミニアプリ プロジェクトに直接リンクできるため、デベロッパーはコンポーネントをすぐに使い始めることができます。
カスタム コンポーネント
ベンダー提供のコンポーネントを使用するだけでなく、デベロッパーはカスタム コンポーネントを作成することもできます。このコンセプトは、WeChat、ByteDance、Alipay、Baidu、Quick App にも存在します。たとえば、Baidu カスタム コンポーネントは、同じフォルダに配置する必要がある 4 つのファイル(custom.swan、custom.css、custom.js、custom.json)で構成されています。
ファイル custom.json は、フォルダの内容をカスタム コンポーネントとして示します。
{
"component": true
}
custom.swan ファイルにはマークアップが、custom.css ファイルには CSS が含まれています。
<view class="name" bindtap="tap">{{name}} {{age}}</view>
.name {
color: red;
}
custom.js ファイルにはロジックが含まれています。コンポーネントのライフサイクル関数は、attached()、detached()、created()、ready() です。コンポーネントは、ページのライフサイクル イベント(show() と hide())にも反応できます。
Component({
properties: {
name: {
type: String,
value: "swan",
},
},
data: {
age: 1,
},
methods: {
tap: function () {},
},
lifetimes: {
attached: function () {},
detached: function () {},
created: function () {},
ready: function () {},
},
pageLifetimes: {
show: function () {},
hide: function () {},
},
});
カスタム コンポーネントは index.json でインポートできます。インポートのキーによって、カスタム コンポーネントが index.swan で使用される名前(ここでは "custom")が決まります。
{
"usingComponents": {
"custom": "/components/custom/custom"
}
}
<view>
<custom name="swanapp"></custom>
</view>
謝辞
この記事は、Joe Medley、Kayce Basques、Milica Mihajlija、Alan Kent、Keith Gu によってレビューされました。