ミニアプリ コンポーネント

ウェブ コンポーネント

当初のウェブ コンポーネントは、デベロッパーがコンポーネントを組み合わせて優れたアプリを構築できるようにすることを期待していました。このようなアトミック コンポーネントの例としては、GitHub の time-elements、Stefan Judis の web-vitals-element、Google のダークモード切り替えなどの恥知らずなプラグがあります。しかし、完全なデザイン システムに関しては、同じベンダーが提供する一貫したコンポーネント セットを人々が好むことがわかっています。SAP の UI5 ウェブ コンポーネントポリマー要素Vaadin の要素、Microsoft の FASTマテリアル ウェブ コンポーネント、そしておそらく AMP コンポーネントなどもあくまでも例です。しかし、この記事では説明しにくい要因があるため、多くのデベロッパーは ReactVue.jsEmber.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.modemode 属性へのデータ バインディング、src 属性への src 属性へのデータ バインディング、3 つのイベント ハンドラ onTaponErroronLoad の同じ名前の関数に対するデータ バインディングに注目してください。に示したように、<image> タグは内部で <div> に変換され、画像の最終サイズのプレースホルダ、オプションの遅延読み込み、デフォルトのソースなどを含みます。

コンポーネントで利用可能な構成オプションはすべて、ドキュメントに記載されています。ドキュメントに埋め込まれたシミュレータを使用したコンポーネント プレビューにより、コードをすぐに具体的な形にできます。

埋め込まれたコンポーネントのプレビューを含む Alipay コンポーネントのドキュメント。シミュレーションされた iPhone 6 でレンダリングされたコンポーネントを示すコードエディタとシミュレータが表示されています。
コンポーネントのプレビューが埋め込まれた Alipay コンポーネントのドキュメント。
別のブラウザタブで実行されている Alipay コンポーネントのプレビュー。シミュレーションされた iPhone 6 でレンダリングされたコンポーネントを示すコードエディタとシミュレータが表示されています。
Alipay コンポーネントのプレビューが専用のタブにポップアウトされました。

各コンポーネントには QR コードもあり、Alipay アプリでスキャンして、自己完結型の最小限のサンプルでコンポーネント サンプルを開きます。

ドキュメント内の QR コードをスキャンした後、実機でプレビューされた Alipay の「image」コンポーネント。
ドキュメントの QR コードリンクに沿って操作した後の、実際のデバイスでの Alipay <image> コンポーネントのプレビュー。

デベロッパーは、独自の URI スキーム antdevtool-tiny:// を使用することで、ドキュメントから Alipay DevTools IDE に直接移動できます。これにより、ドキュメントはインポートするミニアプリ プロジェクトに直接リンクできるため、デベロッパーはすぐにコンポーネントを使い始めることができます。

カスタム コンポーネント

ベンダーが提供するコンポーネントを使用する代わりに、デベロッパーはカスタム コンポーネントを作成することもできます。このコンセプトは、WeChatByteDanceAlipayBaiduQuick App に共通しています。たとえば、Baidu のカスタム コンポーネントは 4 つのファイルで構成され、それぞれ custom.swancustom.csscustom.jscustom.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 MedleyKayce BasquesMilica MihajlijaAlan Kent、Keith Gu によってレビューされました。