ウェブ コンポーネント
当初のウェブ コンポーネントは、デベロッパーがコンポーネントを組み合わせて優れたアプリを構築できるようにすることを期待していました。このようなアトミック コンポーネントの例としては、GitHub の time-elements、Stefan Judis の web-vitals-element、Google のダークモード切り替えなどの恥知らずなプラグがあります。しかし、完全なデザイン システムに関しては、同じベンダーが提供する一貫したコンポーネント セットを人々が好むことがわかっています。SAP の UI5 ウェブ コンポーネント、ポリマー要素、Vaadin の要素、Microsoft の FAST、マテリアル ウェブ コンポーネント、そしておそらく AMP コンポーネントなどもあくまでも例です。しかし、この記事では説明しにくい要因があるため、多くのデベロッパーは React、Vue.js、Ember.js などのフレームワークも利用しています。デベロッパーがこれらのオプションから自由に選択できるようにする(または、ユーザーの視点によっては、デベロッパーがテクノロジーの選択を一律に決めることをforcing)のではなく、スーパーアプリ プロバイダに汎用コンポーネントを用意する必要があります。
ミニアプリのコンポーネント
これらのコンポーネントは、前述した他のコンポーネント ライブラリと同じように考えることができます。利用可能なコンポーネントの概要については、WeChat のコンポーネント ライブラリ、ByteDance のコンポーネント、Alipay のコンポーネント、Baidu の、Quick App コンポーネントをご覧ください。
先ほど説明したように、たとえば WeChat の <image>
は内部ではウェブ コンポーネントですが、これらすべてのコンポーネントが技術的にはウェブ コンポーネントというわけではありません。<map>
や <video>
などの一部のコンポーネントは、WebView の上にレイヤ化される OS 組み込みコンポーネントとしてレンダリングされます。デベロッパーにはこの実装の詳細は公開されず、他のコンポーネントと同様にプログラムされます。
いつものように詳細は異なりますが、プログラミングのコンセプトはどのスーパーアプリ プロバイダでも共通です。重要なコンセプトがデータ バインディングです。以前のマークアップ言語で説明しました。通常、コンポーネントは機能別にグループ化されるため、ジョブに適したものを簡単に見つけることができます。Alipay の分類の例を次に示します。これは、他のベンダーのコンポーネント グループに似ています。
- コンテナを表示する
view
swiper
scroll-view
cover-view
cover-image
movable-view
movable-area
- 基本コンテンツ
text
icon
progress
rich-text
- フォーム コンポーネント
button
form
label
input
textarea
radio
radio-group
checkbox
checkbox-group
switch
slider
picker-view
picker
- ナビゲーション
navigator
- メディア コンポーネント
image
video
- キャンバス
canvas
- 地図
map
- コンポーネントを開く
web-view
lifestyle
contact-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>
に変換され、画像の最終サイズのプレースホルダ、オプションの遅延読み込み、デフォルトのソースなどを含みます。
コンポーネントで利用可能な構成オプションはすべて、ドキュメントに記載されています。ドキュメントに埋め込まれたシミュレータを使用したコンポーネント プレビューにより、コードをすぐに具体的な形にできます。
各コンポーネントには QR コードもあり、Alipay アプリでスキャンして、自己完結型の最小限のサンプルでコンポーネント サンプルを開きます。
デベロッパーは、独自の 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 によってレビューされました。