Ionic Framework 组件系统定义了 UI 组件的构建、打包和向不同 JavaScript 框架公开的方式。本文档解释了 Ionic 基于 Web Component 的架构和实现,包括组件的定义、编译以及与 Angular、React 和 Vue 的集成。
有关特定 UI 组件的信息,请参阅第 2 部分(核心组件)中的相应页面。
Ionic 组件系统基于 Web Component 构建,并使用 Stencil 作为编译器。这种方法允许 Ionic 维护单一的代码库,同时为 Angular、React 和 Vue 提供特定框架的适配器。
来源: core/src/components.d.ts core/stencil.config.ts
Ionic 组件使用 Stencil 实现为 Web Components,Stencil 提供了一个类似 Angular 的声明式 API,但会编译为标准的 Web Components。
来源: core/src/components/input/input.tsx core/src/components/select/select.tsx core/src/components/checkbox/checkbox.tsx
组件使用 Stencil 的 @Component 装饰器进行定义,该装饰器指定了标签名、样式和 Shadow DOM 封装策略。以下是一个典型的组件结构。
组件使用几个关键的装饰器
| 装饰器模式(Decorator) | 目的 | 示例 |
|---|---|---|
@Prop() | 可以从 HTML 设置的公共属性 | @Prop() disabled = false; |
@State() | 未暴露给用户的内部状态 | @State() hasFocus = false; |
@Event() | 组件发出的事件 | @Event() ionChange!: EventEmitter<InputChangeEventDetail>; |
@Method() | 可以从 JavaScript 调用公共方法 | @Method() async setFocus() { ... } |
@Watch() | 属性更改时触发 | @Watch('value') valueChanged() { ... } |
@Element() | 对宿主 DOM 元素的引用 | @Element() el!: HTMLIonInputElement; |
来源: core/src/components/input/input.tsx25-33 core/src/components/select/select.tsx core/src/components/checkbox/checkbox.tsx
Ionic 组件遵循 Stencil 的组件生命周期,其中关键方法在组件生命周期的不同阶段运行。
来源: core/src/components/input/input.tsx366-427 core/src/components/select/select.tsx278-330
Stencil 会自动为所有组件生成 TypeScript 定义,这在使用组件时提供了类型检查和自动补全功能。
生成的 components.d.ts 文件包含了每个组件属性、事件和方法的接口。
来源: core/src/components.d.ts7-46
Ionic 组件使用 CSS 变量进行样式和主题设置,这使得自定义变得容易。
组件使用以下三种封装策略之一
shadow:使用 Shadow DOM 进行完整的样式封装scoped:应用基于属性的样式作用域none:无封装,样式影响全局范围来源: core/src/components/input/input.tsx core/src/components/select/select.tsx
组件公开 CSS 自定义属性(CSS 变量)用于样式设置。
这些 CSS 变量可由用户自定义。
来源: core/src/components/select/select.scss6-44
Ionic 组件作为 Web Components 分发在 @ionic/core 包中,但特定框架的包会适配这些组件,使其能够自然地与每个框架协同工作。
每个支持的框架都有一个包,提供核心 Web Components 的包装器。
来源: packages/angular/src/directives/proxies.ts packages/react/src/components/proxies.ts packages/vue/src/proxies.ts
框架适配器通过 Stencil 配置中的输出目标插件生成。
来源: core/stencil.config.ts72-210
每个框架都有独特集成需求。
Angular 组件被创建为具有 @Input() 和 @Output() 绑定的指令,这些绑定映射到 Web Component 的属性和事件。
来源: packages/angular/src/directives/proxies.ts1-50
React 组件包装了 Web Components,并提供了 React 特有的功能,如 refs 和事件处理。
来源: packages/react/src/components/proxies.ts1-20
Vue 组件包含对 v-model 和其他 Vue 特有功能的特殊处理。
来源: packages/vue/src/proxies.ts87-109
Ionic 组件提供了多项功能来增强组件的可用性。
组件定义了“parts”,允许在 shadow DOM 内进行定向样式设置。
来源: core/src/components/select/select.tsx40-47
组件使用插槽来允许将内容放置在组件的特定部分。
来源: core/src/components/select/select.tsx36-38 core/src/components/input/input.tsx21-24
Ionic 组件与原生表单和特定框架的表单系统集成。
表单组件,如输入框、复选框和选择框,会渲染隐藏的原生输入框以兼容标准的 HTML 表单。
来源: core/src/components/input/input.tsx301-305 core/src/components/checkbox/checkbox.tsx56-86
这是典型的 Ionic 组件结构的示例,以 ion-input 为例
来源: core/src/components/input/input.tsx
组件公开的属性可以通过 HTML 属性或框架属性来设置
属性是在组件类中使用 @Prop() 装饰器定义的
来源: core/src/components/input/input.tsx70-290
组件公开方法,用于程序化交互
来源: core/src/components/input/input.tsx442-462
组件会发出事件,可以进行监听
这些事件可以通过特定于框架的方式进行处理
来源: core/src/components/input/input.tsx302-328
组件被打包成逻辑分组,以实现最佳加载
这种打包方式确保了相关组件一起加载,优化了性能。
来源: core/stencil.config.ts77-118
组件系统会随着时间的推移而发展,并记录了破坏性更改,以帮助开发人员在版本之间进行迁移
主要版本可能会更改组件 API、样式或框架集成。BREAKING.md 文件提供了详细的迁移指南。
Ionic 组件系统是一个强大、结构良好的系统,用于构建跨框架的 UI 组件。它使用 Web Components(通过 Stencil)作为其基础,并提供特定于框架的适配器,以与 Angular、React 和 Vue 进行自然的集成。这种方法允许 Ionic 维护单一的核心代码库,同时为每个支持的框架提供优化的开发人员体验。