
Ionic Framework 5.x 破坏性变更完全指南CSS、组件 API 与主题迁移实战【免费下载链接】ionic-frameworkA powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.项目地址: https://gitcode.com/gh_mirrors/io/ionic-framework本指南以 Ionic Framework 官方 5.x Breaking Changes 文档仓库 BREAKING_ARCHIVE/v5.md为骨架系统梳理从 Ionic 4 升级到 Ionic 5 时所有可能破坏现有应用的变更点涵盖 CSS 工具类、响应式显示类、按压/聚焦/悬停状态变量、组件 API 重命名、默认配色与事件模型调整等。读完本文你将能对照自己的项目逐项排查并完成迁移同时理解这些变更在 core/src 源码中的底层实现依据。目录CSS 层变更CSS 工具类从属性到类的迁移响应式显示类的媒体查询修正按压 / 聚焦 / 悬停状态的变量重构Distributed Sass 移除组件 API 变更Action Sheet 变量重命名Anchor → Router LinkBack Button 与 Card 改用 Shadow DOM控制器组件从 DOM 中移除Header / Footer 的 no-borderList Header 视觉重构Menu 与 Split Panecontent-id 取代 mainNav Link 统一导航组件Radio / Segment / Select Optionvalue 驱动选中态Searchbar字符串化的 show-cancel-button 与 inputmodeSegment 全新 iOS 设计Skeleton Text 移除 widthToast 关闭按钮改为 buttons 数组默认配色更新Events 服务移除Mode 级联继承Ionicons 5迁移检查清单CSS 层变更CSS 工具类从属性到类的迁移Ionic 4 曾提供一批 CSS 工具属性attribute用于快速给组件加 padding、文本对齐等样式。但在多框架支持Ionic for everyone背景下这些属性与 JSX / TypeScript 框架存在冲突因此 Ionic 决定统一改为以ion-前缀的 CSS 类。这样既规避了与原生属性、用户自定义 CSS 的冲突又能保证所有框架行为一致。Ionic 4 的较新版本会在控制台打印弃用警告提示新类名。典型迁移对照完整列表见官方 CSS Utilities 文档Beforeion-header text-center/ion-header ion-content padding/ion-content ion-label text-wrap/ion-label ion-item wrap/ion-itemAfterion-header classion-text-center/ion-header ion-content classion-padding/ion-content ion-label classion-text-wrap/ion-label ion-item classion-wrap/ion-item响应式显示类的媒体查询修正display.css中的响应式显示类.ion-hide-{breakpoint}-down媒体查询语义发生了修正不再使用该断点的最大值如md的991px而是使用该断点的最小值768px。Ionic 断点定义如下断点名宽度xs0sm576pxmd768pxlg992pxxl1200px以前给元素加ion-hide-md-down会在屏幕宽度991px或更小时隐藏现在同样的类会在最大宽度768px时隐藏。各类的媒体查询变化对照类名Ionic 4Ionic 5.ion-hide-downmedia (max-width: 575px)all screen sizes.ion-hide-sm-downmedia (max-width: 767px)media (max-width: 576px).ion-hide-md-downmedia (max-width: 991px)media (max-width: 768px).ion-hide-lg-downmedia (max-width: 1199px)media (max-width: 992px).ion-hide-xl-downall screen sizesmedia (max-width: 1200px)注意.ion-hide-{breakpoint}-up类没有任何改动。从当前仓库源码看这套逻辑至今仍保留在 core/src/css/display.scss 中ion-hide直接display: none !important而每个断点通过media-breakpoint-down($breakpoint, $screen-breakpoints)生成.ion-hide#{$infix}-down类同时该文件还提供了新一代.ion-display-{breakpoint}-{value}显示工具类如ion-display-md-flex源码注释中标注了 TODO(FW-6697) 计划未来移除旧式ion-hide-*类说明迁移方向是统一到新的ion-display-*体系。按压 / 聚焦 / 悬停状态的变量重构自动添加到可点击组件上的.activated类已更名为.ion-activated。同时以下组件的 activated / focused / hover 背景色变量机制被重构Action SheetBack ButtonButtonFAB ButtonItemMenu ButtonSegment ButtonTab Button旧方式要求开发者必须知道各状态叠加层的具体不透明度。以 Material Design 规范为例悬停态是白色叠加层、不透明度0.08。默认样式可能如下--background-hover: rgba(255, 255, 255, 0.08);若想改成黑色叠加层且仍然符合规范就必须手动换算--background-hover: rgba(0, 0, 0, 0.08);新方式额外引入了三个透明度变量--background-activated-opacity --background-focused-opacity --background-hover-opacity这样既保留了精细控制不透明度的能力又允许只设置主变量--background-activated、--background-focused、--background-hover其余交给框架按规范自动补齐。这在全局主题切换时尤为重要更新工具栏颜色会自动同步工具栏内所有按钮无论何种 fill的悬停态无需逐个推算不透明度。示例/* 悬停时按钮背景改为纯红 */ ion-button { --background-hover: red; --background-hover-opacity: 1; } /* Action Sheet 按钮聚焦时背景为半透明绿 */ ion-action-sheet { --button-background-focus: green; --button-background-focus-opacity: 0.5; } /* * FAB 按钮悬停时背景跟随文字颜色 * 保留 md 模式默认的 --background-hover-opacity */ .md ion-fab-button { --color: #222; --background-hover: #222; }这套实现可以从源码中直接印证。例如 core/src/components/button/button.scss 中聚焦、悬停、按压三种状态的背景都是通过--background-*-opacity控制透明度叠加的opacity: var(--background-focused-opacity); /* 聚焦态 */ opacity: var(--background-hover-opacity); /* 悬停态 */ opacity: var(--background-activated-opacity); /* 按压态 */全局 CSS 属性调整部分全局变量被重命名、新增或移除旧变量状态新变量--ion-toolbar-color-uncheckedrenamed--ion-toolbar-segment-color--ion-toolbar-color-checkedrenamed--ion-toolbar-segment-color-checked--ion-toolbar-background-uncheckedrenamed--ion-toolbar-segment-background--ion-toolbar-background-checkedrenamed--ion-toolbar-segment-background-checked--ion-tab-bar-color-activatedrenamed--ion-tab-bar-color-selectedadded--ion-toolbar-segment-indicator-color--ion-toolbar-color-activatedremoved--ion-item-background-activatedremoved--ion-item-background-focusedremoved--ion-item-background-hoverremovedDistributed Sass 移除dist/目录下的scss文件已被删除。主题定制应统一改用 CSS 变量Custom Properties不再依赖直接编译 Sass 源文件。组件 API 变更Action Sheet 变量重命名ion-action-sheet的 CSS 变量发生重命名与新增且统一加上button前缀旧变量新变量--button-background--background-activated--button-background-activated--button-background-activated-opacity--background-selected--button-background-selected--button-background-focused--button-background-focused-opacity--button-background-hover--button-background-hover-opacity--button-background-selected--button-background-selected-opacity--button-color--button-color-activated--button-color-focused--button-color-hover--button-color-selected源码 core/src/components/action-sheet/action-sheet.scss 中即可看到这些变量的实际消费逻辑按压态使用opacity: var(--button-background-activated-opacity)聚焦态使用opacity: var(--button-background-focused-opacity)并兼容--button-background-selected-opacity回退悬停态使用opacity: var(--button-background-hover-opacity)。Anchor → Router Linkion-anchor组件被重命名为ion-router-link以更准确地表达它应配合路由使用的语义。该组件仍然只适用于 vanilla JavaScript 与 Stencil 项目Angular 项目应继续使用arouterLink配合 Angular Router。Back Button 与 Card 改用 Shadow DOMion-back-button转换为使用 shadow DOMion-card转换为使用 shadow DOM。使用 shadow DOM 意味着组件内部样式被隔离全局 CSS 选择器将无法直接命中组件内部元素样式覆盖应通过暴露的 CSS 自定义属性进行。控制器组件从 DOM 中移除控制器组件ion-action-sheet-controller、ion-alert-controller、ion-loading-controller、ion-menu-controller、ion-modal-controller、ion-picker-controller、ion-popover-controller、ion-toast-controller不再作为元素存在于 Ionic core 中应改为从ionic/core直接导入控制器对象。使用 Angular / React 的项目不受影响。Beforevanilla JSion-loading-controller/ion-loading-controller script async function presentLoading() { const loadingController document.querySelector(ion-loading-controller); const loading await loadingController.create({ message: Hello, duration: 2000, }); await loading.present(); } /scriptAftervanilla JSscript typemodule import { loadingController } from ionic/core; window.loadingController loadingController; /script script async function presentLoading() { const loading await loadingController.create({ message: Hello, duration: 2000, }); await loading.present(); } /script此变更适用于所有控制器元素本文以 loading controller 为例。Header / Footer 的 no-borderion-header/ion-footer的no-border属性被移除改用ion-no-border类原因与前述 CSS 工具类迁移一致。List Header 视觉重构ion-list-header按最新 iOS 规范重新设计旧设计是小字号、大写字母新设计是更大更粗的字体可能导致应用视觉变化。此外ion-list-header内的文本内容应包裹在ion-label中否则按钮对齐可能出现偏差。Beforeion-list-header New This Week ion-buttonSee All/ion-button /ion-list-headerAfterion-list-header ion-labelNew This Week/ion-label ion-buttonSee All/ion-button /ion-list-header同时list header 内的按钮默认改为fillclear和sizesmall。若想恢复旧外观可通过自定义 CSS 或按钮属性实现。Menu 与 Split Panecontent-id 取代 mainion-menu的变更Angular 中swipeEnable()方法被移除改用swipeGesture()side取值left/right被移除改用start/end移除main属性改用content-idvanilla JS / Vue或contentIdAngular / Reactios模式下呈现类型presentation type默认改为overlay。Beforeion-menu.../ion-menu ion-content main.../ion-contentAfterion-menu content-idmain/ion-menu ion-content idmain.../ion-content从 core/src/components/menu/menu.tsx 的实现看contentId属性会被document.getElementById(this.contentId)解析以关联主内容视图而swipeGesture属性默认true直接控制侧滑手势的启用与停用this.gesture.enable(isActive this.swipeGesture)这正是swipeGesture()方法背后的属性驱动实现。ion-split-pane同样移除了main属性Beforeion-split-pane ... div main.../div /ion-split-paneAfterion-split-pane content-idmain ... div idmain.../div /ion-split-pane同时ion-split-pane也转换为使用 shadow DOM。Nav Link 统一导航组件ion-nav-push、ion-nav-back、ion-nav-set-root三个组件被移除统一由ion-nav-link配合router-direction属性实现该属性接受root、forward、back。这样避免了多个只差过渡方向的重复组件。Radio / Segment / Select Optionvalue 驱动选中态Radioion-radio必须放在ion-radio-group内即使只有一个ion-radio也是如此。checked属性被移除改为在父级ion-radio-group上设置value来匹配选中项。ion-radio不再发射ionSelect事件应监听ion-radio-group发射的ionChange事件。Beforeion-radio checkedOne/ion-radio ion-radio-group ion-radioOne/ion-radio ion-radio checkedTwo/ion-radio /ion-radio-groupAfterion-radio-group valueone ion-radio valueoneOne/ion-radio /ion-radio-group ion-radio-group valuetwo ion-radio valueoneOne/ion-radio ion-radio valuetwoTwo/ion-radio /ion-radio-group源码印证在 core/src/components/radio-group/radio-group.tsx 中ionChange事件由 radio-group 在值变化时通过this.ionChange.emit({ value, event })发出core/src/components/radio/radio.tsx 中单个 radio 的选中态由isOptionSelected(radioGroupValue, this.value, compareWith)计算得出即选中完全由父级 value 与自身 value 的匹配关系决定。Segment Buttonchecked属性被移除同样改为在父级ion-segment上设置valueBeforeion-segment ion-segment-buttonOne/ion-segment-button ion-segment-button checkedTwo/ion-segment-button ion-segment-buttonThree/ion-segment-button /ion-segmentAfterion-segment valuetwo ion-segment-button valueoneOne/ion-segment-button ion-segment-button valuetwoTwo/ion-segment-button ion-segment-button valuethreeThree/ion-segment-button /ion-segmentSelect Optionselected属性被移除改为在父级ion-select上设置valueBeforeion-select ion-select-optionOne/ion-select-option ion-select-option selectedTwo/ion-select-option /ion-selectAfterion-select valuetwo ion-select-option valueoneOne/ion-select-option ion-select-option valuetwoTwo/ion-select-option /ion-selectSearchbar字符串化的 show-cancel-button 与 inputmodeion-searchbar的show-cancel-button不再接受布尔值只接受字符串focus、always、never。Beforeion-searchbar show-cancel-button ion-searchbar show-cancel-buttontrue ion-searchbar show-cancel-buttonfalseAfterion-searchbar show-cancel-buttonfocus ion-searchbar show-cancel-buttonfocus ion-searchbar show-cancel-buttonnever源码 core/src/components/searchbar/searchbar.tsx 中属性声明为Prop() showCancelButton: never | focus | always never渲染逻辑只在showCancelButton ! never时渲染取消按钮且focus模式需要搜索框处于聚焦状态this.showCancelButton focus !this.focused时不显示。另外inputmode属性默认值改为undefined要恢复旧行为需显式设置inputmodesearch。Segment 全新 iOS 设计ion-segment在 5.x 中被彻底重做采用全新 iOS 设计并引入一套同时适用于 Material Design 与 iOS 的全新手势。因此引入了一系列破坏性变更事件重命名ion-segment不再发射ionSelect应监听ion-segment上的ionChange。从 core/src/components/segment/segment.tsx 可以看到ionChange只在用户提交操作如点击或拖拽结束时通过this.ionChange.emit({ value })发射而程序化赋值value不会触发它ionSelect则被保留为内部值每次变化无论内外都会触发的语义事件。按钮状态移除了激活态样式与相关自定义属性--color-activated、--background-activated新规范用 indicator 与 ripple 表现激活聚焦 / 悬停状态按前述统一方案更新。指示器颜色--indicator-color现在作用于被选中的 segment buttonios与md均如此--indicator-color-checked被移除Material Design 规范对未选中按钮不设指示器颜色若要还原旧规范样式如 md 模式下始终显示底部线条使用自定义 CSS.md ion-segment::after { position: absolute; bottom: 0; height: 2px; width: 100%; content: ; background: rgba(0, 0, 0, 0.5); z-index: -1; }背景与颜色为ion-segment新增--background变量。相应地子级 segment button 的背景变量需设置在ion-segment-button上--background: Background of the segment button --background-checked: Background of the checked segment button --background-disabled: Background of the disabled segment button --background-hover: Background of the segment button on hover注意iOS 不再检查按钮背景色设置--background-checked可能产生非预期效果。iOS 下 Segment 通过指示器在按钮间滑动来标示选中项。上述变量设置在ion-segment上不会被子按钮继承。所有颜色变量也应在按钮上设置以保证一致--color: Color of the segment button --color-checked: Color of the checked segment button --color-disabled: Color of the disabled segment button --color-hover: Color of the segment button on hover移除的变量当前规范不再使用--color-checked-disabled--background-disabled--color-disabled--background-activated--color-activated全局 CSS 属性重命名/新增情况与前述 CSS 小节一致此处单列旧变量状态新变量--ion-toolbar-color-uncheckedrenamed--ion-toolbar-segment-color--ion-toolbar-color-checkedrenamed--ion-toolbar-segment-color-checked--ion-toolbar-background-uncheckedrenamed--ion-toolbar-segment-background--ion-toolbar-background-checkedrenamed--ion-toolbar-segment-background-checkedadded--ion-toolbar-segment-indicator-colorSkeleton Text 移除 widthion-skeleton-text的width属性被移除改由 CSS 样式控制宽度。Toast 关闭按钮改为 buttons 数组ion-toast的showCloseButton与closeButtonText属性被移除改用buttons数组并配合role: cancel。Beforeasync presentToast() { const toast await this.toastController.create({ message: Your settings have been saved., showCloseButton: true, closeButtonText: Close }); toast.present(); }Afterasync presentToast() { const toast await this.toastController.create({ message: Your settings have been saved., buttons: [ { text: Close, role: cancel, handler: () { console.log(Close clicked); } } ] }); toast.present(); }从类型定义 core/src/components/toast/toast-interface.ts 可以看到buttons接受(ToastButton | string)[]而ToastButton中的role是LiteralUnioncancel, string即cancel作为内置语义角色参与按钮行为判定。默认配色更新Ionic 5 更新了默认颜色primary: #3880ff secondary: #3dc2ff tertiary: #5260ff success: #2dd36f warning: #ffc409 danger: #eb445a light: #f4f5f8 medium: #92949c dark: #222428其中primary、light、dark未变warning的对比色contrast color更新为#000。如果你没有使用官方 starter 且未覆盖默认值才会受到影响若已覆盖默认值可按需手动更新。补充说明当前仓库更新版本的主题源文件 core/src/themes/ionic.theme.default.scss 已演进为primary: #0054e9、secondary: #0163aa等更新的配色且依然保留warning: #ffc409、light: #f4f5f8、dark: #222428等延续自 5.x 的取值。本文表格给出的是 v5 发布时的默认值若需还原 v5 视觉应以历史 tag 为准。Events 服务移除ionic/angular的 Events 服务被移除。替代方案使用 Observables 实现类似的发布/订阅架构使用 Redux 做更进阶的状态管理。Mode 级联继承Mode 现在从父组件级联到子组件。以前想让某个组件及其子组件统一使用md模式需要在所有组件上设置modemdion-segment modemd ion-segment-button modemdButton/ion-segment-button ion-segment-button modemdButton/ion-segment-button /ion-segment现在只需在ion-segment上设置一次子组件自动继承若不想继承可在子组件上单独设置不同的 mode。Ionicons 5Ionicons 5 正式发布带来大量变化所有图标自上而下重新绘制、每个图标提供多个变体filled、outline、sharp并且移除了根据平台自动切换图标的行为。迁移检查清单完成上述阅读后可对照以下清单逐项排查你的应用CSS 工具属性全局搜索text-center、padding、text-wrap、wrap、no-border等属性用法替换为ion-前缀类显示类检查.ion-hide-{bp}-down的隐藏阈值是否符合新语义基于断点最小值状态变量把依赖具体不透明度的--background-hover等写法改为主变量 --*-opacity组合控制器元素vanilla JS / Vue 项目移除ion-*-controller标签改为从ionic/core导入选中态ion-radio/ion-segment-button/ion-select-option的checked/selected改为父组件value驱动事件监听ionSelect迁移到ionChangeradio 监听ion-radio-groupsegment 监听ion-segmentMenu / Split Panemain属性改为content-id/contentIdMenu 的left/right改start/endToastshowCloseButton/closeButtonText改为buttons数组 role: cancelNavion-nav-push/ion-nav-back/ion-nav-set-root迁移到ion-nav-linkrouter-direction配色确认是否依赖旧的默认色值按需更新为 v5 默认配色。【免费下载链接】ionic-frameworkA powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.项目地址: https://gitcode.com/gh_mirrors/io/ionic-framework创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考