ion-modal
模态是一个出现在应用内容顶部的对话框,必须由应用关闭才能恢复交互。它在需要从众多选项中进行选择或筛选列表中的项目时非常有用,当然还有许多其他用例。
内联模态(推荐)
ion-modal
可以通过在模板中直接编写组件来使用。这减少了您需要连接的处理程序数量才能显示模态。
在使用 ion-modal
与 Angular、React 或 Vue 时,您传入的组件会在模态关闭时销毁。由于此功能由 JavaScript 框架提供,因此在没有 JavaScript 框架的情况下使用 ion-modal
不会销毁您传入的组件。如果需要此功能,我们建议使用 modalController
。
使用 isOpen
ion-modal
上的 isOpen
属性允许开发人员从其应用程序状态控制模态的显示状态。这意味着当 isOpen
设置为 true
时,模态将显示,而当 isOpen
设置为 false
时,模态将关闭。
isOpen
使用单向数据绑定,这意味着当模态关闭时,它不会自动设置为 false
。开发人员应该监听 ionModalDidDismiss
或 didDismiss
事件并将 isOpen
设置为 false
。这样做的原因是为了防止 ion-modal
的内部结构与应用程序的状态紧密耦合。使用单向数据绑定,模态只需要关心响应式变量提供的布尔值。使用双向数据绑定,模态需要关心布尔值以及响应式变量本身的存在。这会导致非确定性行为,并使应用程序更难调试。
控制器模态
借助 modalController
,开发人员可以以编程方式显示 ion-modal
。开发人员将完全控制何时显示和关闭模态。
阻止模态关闭
在向模态中输入数据时,通常希望有一种方法来防止意外数据丢失。ion-modal
上的 canDismiss
属性让开发人员可以控制何时允许关闭模态。
使用 canDismiss
属性有两种不同的方式:设置布尔值或设置回调函数。
注意:使用表格模态时,如果未设置 0
断点,则 canDismiss
不会在滑动时进行检查。但是,在按 Esc
或硬件后退按钮时,它仍将进行检查。
设置布尔值
开发人员可以将 canDismiss
设置为布尔值。如果 canDismiss
为 true
,则当用户尝试关闭模态时,模态将关闭。如果 canDismiss
为 false
,则当用户尝试关闭模态时,模态将不会关闭。
当您需要在关闭模态之前需要执行特定操作时,应该使用设置布尔值。例如,如果开发人员希望在关闭模态之前要求选中“使用条款”复选框,他们可以先将 canDismiss
设置为 false
,然后在选中复选框后将其更新为 true
。
设置回调函数
开发人员可以将 canDismiss
设置为一个函数。此函数必须返回一个解析为 true
或 false
的 Promise
。如果 promise 解析为 true
,则模态将关闭。如果 promise 解析为 false
,则模态将不会关闭。
当您有复杂的关闭条件(例如,在关闭模态之前显示确认对话框)时,应该使用设置回调函数。然后,用户在此对话框中选择的选项可以用来确定模态是否应该继续关闭。
请注意,当使用卡片或表格模态时,设置回调函数会导致滑动手势中断。这是因为 Ionic 事先不知道您的回调函数将解析为什
阻止滑动关闭
开发人员可能希望阻止用户滑动关闭卡片或表格模态。可以通过为 canDismiss
设置回调函数并检查 role
是否不为 gesture
来实现这一点。
在子组件中修改关闭行为
在某些情况下,开发人员可能需要根据显示的模态的状态来自定义 canDismiss
回调的行为。这种自定义特别有用,例如,当开发人员希望在其中的表单无效时阻止关闭模态。
为了实现这种自定义,子组件可以使用各种技术,例如函数回调、事件发射或其他响应式机制来与父组件通信并更新控制 canDismiss
回调的条件。
以下是一个简化的示例,说明子组件如何与父组件交互以修改 canDismiss
回调
卡片模态
开发人员可以创建一个卡片模态效果,其中模态显示为叠加在应用程序主要内容顶部的卡片。要创建卡片模态,开发人员需要在 ion-modal
上设置 presentingElement
属性。
presentingElement
属性接受对应该在模态下方显示的元素的引用。这通常是对 ion-router-outlet
的引用。
canDismiss
属性可以用来控制卡片模态是否可以滑动关闭。
卡片显示样式仅在 iOS 上可用。
表格模态
内容 应该在 sheet 模态框内部使用,如果你想让你的模态框内容可滚动。
开发者可以创建一个类似于地图应用中抽屉组件的 sheet 模态框效果。要创建一个 sheet 模态框,开发者需要在 ion-modal
上设置 breakpoints
和 initialBreakpoint
属性。
breakpoints
属性接受一个数组,该数组表示 sheet 在滑动时可以捕捉到的每个断点。breakpoints
属性为 [0, 0.5, 1]
表示 sheet 可以滑动到显示模态框的 0%、50% 和 100%。当模态框滑动到 0% 时,模态框将自动关闭。注意,如果未包含 0
断点,则模态框在滑动时不能关闭,但仍然可以通过按 Esc
键或硬件后退按钮关闭。
initialBreakpoint
属性是必需的,这样 sheet 模态框就知道在呈现时从哪个断点开始。initialBreakpoint
值也必须存在于 breakpoints
数组中。给定 breakpoints
值为 [0, 0.5, 1]
,initialBreakpoint
值为 0.5
是有效的,因为 0.5
存在于 breakpoints
数组中。initialBreakpoint
值为 0.25
是无效的,因为 0.25
不存在于 breakpoints
数组中。
backdropBreakpoint
属性可用于自定义 ion-backdrop
开始淡入的点。当创建具有 sheet 下方内容的界面时,这很有用,这些内容应该保持交互性。一个常见的用例是 sheet 模态框覆盖地图,其中地图在 sheet 完全展开之前是交互式的。
与背景内容交互
自定义 Sheet 高度
开发者应该使用 --height
CSS 变量来更改 sheet 模态框的高度,而不是更改 breakpoints
数组中的最后一个断点。这样做的原因是,将 breakpoints
数组中的最后一个断点更改为小于 1
的值会导致部分模态框在视窗之外不可访问。
以下示例演示了如何获取根据其内容自动调整大小的 sheet 模态框。注意,通过将最大断点保持在 1
,我们确保整个模态框在视窗中可访问。
处理行为
sheet 模态框可以选择性地渲染一个用于在断点之间拖动 sheet 的处理指示器。handleBehavior
属性可用于配置用户激活处理时的行为。
样式
模态框在应用程序的根目录呈现,因此它们覆盖整个应用程序。此行为适用于内联模态框和从控制器呈现的模态框。因此,自定义模态框样式不能作用域到特定组件,因为它们不会应用于模态框。相反,样式必须全局应用。对于大多数开发者来说,将自定义样式放在 global.css
中就足够了。
如果你正在构建一个 Ionic Angular 应用程序,则需要将样式添加到全局样式表文件。有关更多信息,请阅读下面 Angular 部分中的样式放置。
ion-modal
假设堆叠的模态框大小相同。因此,每个后续模态框都不会有阴影,并且背景透明度为 0
。这样做是为了避免阴影和背景随着添加的每个模态框变暗的效果。可以通过设置 --box-shadow
和 --backdrop-opacity
CSS 变量来更改此行为。
ion-modal.stack-modal {
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
动画
可以通过使用我们的动画构建器并将动画分配给 enterAnimation
和 leaveAnimation
来自定义进入和离开动画。
自定义对话框
虽然 ion-modal
最常用于全页视图、卡片或 sheet,但也可以将其用于自定义对话框。如果开发者需要比 ion-alert 或 ion-loading 等组件提供的界面更复杂的界面,这将很有用。
在创建自定义对话框时,需要牢记以下几点
ion-content
旨在用于全页模态框、卡片和 sheet。如果你的自定义对话框具有动态或未知大小,则不应该使用ion-content
。- 创建自定义对话框提供了一种从默认模态框体验中退出。因此,不应将自定义对话框与卡片或 sheet 模态框一起使用。
接口
ModalOptions
下面你会发现使用 modalController
时可用的所有选项。调用 modalController.create()
时,应该提供这些选项。
interface ModalOptions {
component: any;
componentProps?: { [key: string]: any };
presentingElement?: HTMLElement;
showBackdrop?: boolean;
backdropDismiss?: boolean;
cssClass?: string | string[];
animated?: boolean;
canDismiss?: boolean | ((data?: any, role?: string) => Promise<boolean>);
mode?: 'ios' | 'md';
keyboardClose?: boolean;
id?: string;
htmlAttributes?: { [key: string]: any };
enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
breakpoints?: number[];
initialBreakpoint?: number;
backdropBreakpoint?: number;
handle?: boolean;
}
ModalCustomEvent
虽然不是必需的,但可以使用此接口代替 CustomEvent
接口,以便与从该组件发出的 Ionic 事件进行更强的类型化。
interface ModalCustomEvent extends CustomEvent {
target: HTMLIonModalElement;
}
可访问性
键盘交互
键 | 描述 |
---|---|
Esc | 关闭模态框 |
标签
模态框具有 dialog
角色。因此,开发者 **必须** 正确地为他们的模态框添加标签。如果模态框使用 ion-title
,则可以通过在 ion-modal
上设置 aria-labelledby
来使用里面的文本为模态框本身添加标签。如果模态框包含其他描述性文本,则可以使用 aria-describedby
将此文本与模态框相关联。
屏幕阅读器
模态框已应用 aria-modal
属性。此属性会导致辅助技术限制导航到模态框元素的内容。因此,使用移动到下一个或上一个项目的姿态可能不会聚焦模态框之外的元素。即使在使用 backdropBreakpoint
属性在 sheet 模态框中禁用背景的情况下,也是如此。
如果开发者手动移动焦点,辅助技术不会限制导航到模态框元素的内容。但是,对于启用焦点捕获的模态框,Ionic 不支持手动将焦点移动到模态框之外。
有关更多信息,请参阅 https://w3c.github.io/aria/#aria-modal。
焦点捕获
呈现模态框时,焦点将被捕获到呈现的模态框内。用户可以聚焦模态框内的其他交互式元素,但永远无法在模态框呈现时聚焦模态框之外的交互式元素。对于呈现多个堆叠模态框的应用程序,焦点将被捕获到最后呈现的模态框上。
通过 backdropBreakpoint
属性禁用背景的 sheet 模态框不受焦点捕获的影响。
Sheet 模态框
当使用 backdropBreakpoint
属性时,sheet 模态框允许用户与模态框后面的内容进行交互。背景将在指定的 backdropBreakpoint
及其之前被禁用,并在其之后被启用。
当背景被禁用时,用户可以使用指针或键盘与 sheet 模态框之外的元素进行交互。由于使用了 aria-modal
,辅助技术可能默认情况下无法聚焦 sheet 模态框之外。我们建议避免使用自动聚焦等功能,因为它会导致辅助技术在两个交互式上下文之间跳转,而不会警告用户。
性能
安装内部内容
内联 ion-modal
的内容在关闭时将被卸载。如果此内容的渲染成本很高,开发者可以使用 keepContentsMounted
属性在模态框安装后立即安装内容。这有助于优化应用程序的响应能力,因为内部内容在模态框打开时将已安装。
开发者在使用 keepContentsMounted
时应该牢记以下几点
-
此功能应该作为最后的手段使用,以解决现有的性能问题。尝试在使用此功能之前识别并解决性能瓶颈。此外,不要使用此功能来预测性能问题。
-
此功能仅在使用 JavaScript 框架时需要。不使用框架的开发者可以将要渲染的内容传递到模态框中,内容将自动渲染。
-
此功能仅适用于内联模态框。使用
modalController
创建的模态框不会提前创建,因此也不会创建内部内容。 -
内部组件上的任何 JavaScript 框架生命周期钩子将在模态框安装后立即运行,而不是在模态框呈现时运行。
属性
animated
描述 | 如果为 true ,模态框将进行动画。 |
属性 | animated |
类型 | boolean |
默认值 | true |
backdropBreakpoint
描述 | 一个介于 0 到 1 之间的十进制值,它表示在使用 sheet 模态框时背景开始淡入的点。在此点之前,背景将被隐藏,并且可以与 sheet 下面的内容进行交互。此值是排他的,这意味着背景将在指定值之后变为活动状态。 |
属性 | backdrop-breakpoint |
类型 | number |
默认值 | 0 |
backdropDismiss
描述 | 如果为 true ,单击背景时模态框将关闭。 |
属性 | backdrop-dismiss |
类型 | boolean |
默认值 | true |
breakpoints
描述 | 创建 sheet 模态框时要使用的断点。数组中的每个值都必须是介于 0 和 1 之间的十进制数,其中 0 表示模态框已完全关闭,1 表示模态框已完全打开。这些值相对于模态框的高度,而不是屏幕的高度。此数组中的一个值必须是 initialBreakpoint 属性的值。例如:[0, .25, .5, 1] |
属性 | undefined |
类型 | number[] | undefined |
默认值 | undefined |
canDismiss
描述 | 确定调用dismiss 方法时模态框是否可以关闭。如果值为 true 或值的函数返回true ,则在尝试关闭时模态框将关闭。如果值为false 或值的函数返回false ,则在尝试关闭时模态框将不会关闭。如果您需要从回调函数中访问 this ,请参阅https://ionic.js.cn/docs/troubleshooting/runtime#accessing-this。 |
属性 | can-dismiss |
类型 | ((data?: any, role?: string | undefined) => Promise<boolean>) | boolean |
默认值 | true |
enterAnimation
描述 | 模态框显示时使用的动画。 |
属性 | undefined |
类型 | ((baseEl: any, opts?: any) => Animation) | undefined |
默认值 | undefined |
focusTrap
描述 | 如果为true ,则不允许焦点移出此覆盖层。如果为false ,则允许焦点移出覆盖层。在大多数情况下,此属性应保持设置为 true 。将此属性设置为false 会导致严重的辅助功能问题,因为依赖辅助技术的用户可能会将焦点移动到一个令人困惑的状态。我们建议只有在绝对必要时才将其设置为false 。开发人员可能希望考虑禁用焦点捕获,如果此覆盖层从第三方库中呈现了一个非Ionic覆盖层。开发人员会在呈现第三方覆盖层时禁用Ionic覆盖层的焦点捕获,然后在关闭第三方覆盖层并将焦点移回Ionic覆盖层时重新启用焦点捕获。 |
属性 | focus-trap |
类型 | boolean |
默认值 | true |
handle
描述 | 显示在表单模态框顶部的水平线。在设置breakpoints 和initialBreakpoint 属性时,默认情况下它为true 。 |
属性 | handle |
类型 | boolean | undefined |
默认值 | undefined |
handleBehavior
描述 | 按下句柄时表单模态框的交互行为。 默认值为 "none" ,这意味着按下句柄时模态框不会改变大小或位置。设置为"cycle" 以让模态框在按下时在可用断点之间循环。当 handle 属性设置为false 或breakpoints 属性未设置(使用全屏或卡片模态框)时,句柄行为不可用。 |
属性 | handle-behavior |
类型 | "cycle" | "none" | undefined |
默认值 | 'none' |
htmlAttributes
描述 | 传递给模态框的附加属性。 |
属性 | undefined |
类型 | undefined | { [key: string]: any; } |
默认值 | undefined |
initialBreakpoint
描述 | 一个介于 0 到 1 之间的十进制值,指示创建表单模态框时模态框将打开的初始点。此值也必须列在breakpoints 数组中。 |
属性 | initial-breakpoint |
类型 | number | undefined |
默认值 | undefined |
isOpen
描述 | 如果为true ,模态框将打开。如果为false ,模态框将关闭。如果您需要对展示进行更细粒度的控制,请使用此方法,否则只需使用模态框控制器或trigger 属性。注意:isOpen 在模态框关闭时不会自动设置为false 。您需要在代码中执行此操作。 |
属性 | is-open |
类型 | boolean |
默认值 | false |
keepContentsMounted
描述 | 如果为true ,传递到ion-modal 中的组件将在创建模态框时自动挂载。即使模态框关闭,组件也会保持挂载状态。但是,组件将在模态框销毁时销毁。此属性不是反应性的,应该只在最初创建模态框时使用。注意:此功能仅适用于Angular、React和Vue等JavaScript框架中的内联模态框。 |
属性 | keep-contents-mounted |
类型 | boolean |
默认值 | false |
keyboardClose
描述 | 如果为true ,则在显示覆盖层时键盘将自动关闭。 |
属性 | keyboard-close |
类型 | boolean |
默认值 | true |
leaveAnimation
描述 | 模态框关闭时使用的动画。 |
属性 | undefined |
类型 | ((baseEl: any, opts?: any) => Animation) | undefined |
默认值 | undefined |
mode
描述 | 模式决定使用哪个平台样式。 |
属性 | mode |
类型 | "ios" | "md" |
默认值 | undefined |
presentingElement
描述 | 显示模态框的元素。这用于卡片显示效果以及将多个模态框堆叠在一起。仅适用于iOS模式。 |
属性 | undefined |
类型 | HTMLElement | undefined |
默认值 | undefined |
showBackdrop
描述 | 如果为true ,将在模态框后面显示一个背景。此属性控制模态框显示时背景是否使屏幕变暗。它不控制背景是否处于活动状态或是否存在于DOM中。 |
属性 | show-backdrop |
类型 | boolean |
默认值 | true |
trigger
描述 | 与触发元素的ID相对应,该触发元素在被点击时会导致模态框打开。 |
属性 | trigger |
类型 | string | undefined |
默认值 | undefined |
Events
名称 | 描述 | 冒泡 |
---|---|---|
didDismiss | 模态框关闭后发出。是ionModalDidDismiss的简写。 | true |
didPresent | 模态框显示后发出。是ionModalDidPresent的简写。 | true |
ionBreakpointDidChange | 模态框断点更改后发出。 | true |
ionModalDidDismiss | 模态框关闭后发出。 | true |
ionModalDidPresent | 模态框显示后发出。 | true |
ionModalWillDismiss | 模态框关闭前发出。 | true |
ionModalWillPresent | 模态框显示前发出。 | true |
willDismiss | 模态框关闭前发出。是ionModalWillDismiss的简写。 | true |
willPresent | 模态框显示前发出。是ionModalWillPresent的简写。 | true |
Methods
dismiss
描述 | 模态框覆盖层显示后,关闭它。 |
签名 | dismiss(data?: any, role?: string) => Promise<boolean> |
getCurrentBreakpoint
描述 | 返回表单样式模态框的当前断点 |
签名 | getCurrentBreakpoint() => Promise<number | undefined> |
onDidDismiss
描述 | 返回一个promise,当模态框关闭时解析。 |
签名 | onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
onWillDismiss
描述 | 返回一个promise,当模态框将要关闭时解析。 |
签名 | onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>> |
present
描述 | 创建模态框覆盖层后,显示它。 |
签名 | present() => Promise<void> |
setCurrentBreakpoint
描述 | 将表单样式模态框移动到特定断点。断点值必须是您breakpoints 数组中定义的值。 |
签名 | setCurrentBreakpoint(breakpoint: number) => Promise<void> |
CSS Shadow Parts
名称 | 描述 |
---|---|
backdrop | ion-backdrop 元素。 |
content | 默认插槽的包装元素。 |
handle | 当handle="true" 时显示在表单模态框顶部的句柄。 |
CSS Custom Properties
- iOS
- MD
名称 | 描述 |
---|---|
--backdrop-opacity | 背景的不透明度 |
--background | 模态框内容的背景 |
--border-color | 模态框内容的边框颜色 |
--border-radius | 模态框内容的边框半径 |
--border-style | 模态框内容的边框样式 |
--border-width | 模态框内容的边框宽度 |
--height | 模态框的高度 |
--max-height | 模态框的最大高度 |
--max-width | 模态框的最大宽度 |
--min-height | 模态框的最小高度 |
--min-width | 模态框的最小宽度 |
--width | 模态框的宽度 |
名称 | 描述 |
---|---|
--backdrop-opacity | 背景的不透明度 |
--background | 模态框内容的背景 |
--border-color | 模态框内容的边框颜色 |
--border-radius | 模态框内容的边框半径 |
--border-style | 模态框内容的边框样式 |
--border-width | 模态框内容的边框宽度 |
--height | 模态框的高度 |
--max-height | 模态框的最大高度 |
--max-width | 模态框的最大宽度 |
--min-height | 模态框的最小高度 |
--min-width | 模态框的最小宽度 |
--width | 模态框的宽度 |
Slots
名称 | 描述 |
---|---|
`` | 内容放置在.modal-content 元素中。 |