Web 组件
Web 组件从一开始就承诺让开发者能够将其拼接在一起,并在此基础上构建出出色的应用。此类原子组件的示例包括 GitHub 的 time-elements、Stefan Judis 的 web-vitals-element,或者(不客气地提一下)Google 的深色模式切换开关。不过,我发现,对于完整的设计系统,用户更倾向于使用来自同一供应商的一组协调一致的组件。以下列举的示例并不详尽,其中包括 SAP 的 UI5 Web 组件、Polymer 元素、Vaadin 元素、Microsoft 的 FAST、Material Web 组件、可能的 AMP 组件,以及许多其他组件。不过,由于本文不涉及的许多因素,许多开发者也纷纷采用了 React、Vue.js、Ember.js 等框架。超级应用提供商普遍提供开发者必须使用的一组组件,而不是让开发者自由选择其中任何一种(或者,根据您的观点,强迫他们做出技术选择)。
迷你应用中的组件
您可以将这些组件视为上述任何组件库。如需大致了解可用组件,您可以浏览 WeChat 的组件库、ByteDance 的组件、支付宝的组件、百度和快应用组件。
我之前已经指出,例如,微信的 <image> 在底层是 Web 组件,但从技术层面讲,并非所有这些组件都是 Web 组件。某些组件(例如 <map> 和 <video>)会呈现为叠加在 WebView 上的操作系统内置组件。对于开发者而言,此实现细节不会显示,它们的编程方式与任何其他组件一样。
一如既往,具体细节会有所不同,但所有超级应用提供商的整体编程概念都是相同的。一个重要的概念是数据绑定,如标记语言中所述。通常,组件会按功能分组,以便您更轻松地找到适合任务的组件。以下是来自支付宝分类的示例,与其他供应商的组件分组类似。
- 查看容器
- 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
 
在下方,您可以看到 Alipay 的 <image> 用于 a:for 指令(请参阅列表渲染),该指令会循环处理 index.js 中提供的图片数据数组。
/* 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 属性以及三个事件处理脚本 onTap、onError 和 onLoad 与同名函数的数据绑定。如前面所示,<image> 标记会在内部转换为 <div>,其中包含图片最终尺寸的占位符、可选的延迟加载、默认来源等。
文档中列出了该组件的所有可用配置选项。嵌入文档中的带有模拟器的组件预览可让您立即直观地了解代码。
 
   
  每个组件还都有一个二维码,可使用 Alipay 应用进行扫描,以便在自包含的极小示例中打开组件示例。
 
  <image> 组件。
  开发者可以利用专有 URI 方案 antdevtool-tiny://,从文档直接跳转到 Alipay DevTools IDE。这样,文档就可以直接关联到要导入的迷你应用项目,以便开发者立即开始使用该组件。
自定义组件
除了使用供应商提供的组件之外,开发者还可以创建自定义组件。WeChat、ByteDance、Alipay、百度以及快应用都支持此概念。例如,百度自定义组件由四个必须位于同一文件夹中的文件组成: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 审核。
