Ionic3与Ionic4变更对比

ionic 了,以后都 angular 了。命名方式都用 angular 的了; provider 也改成 angular 的叫法了,以后请叫 service

首先,我们还是以传统的 angular 来使用之

ionic start   [options]

ionic start myApp
ionic start myApp blank
ionic start myApp tabs --cordova
ionic start myApp tabs --capacitor
ionic start myApp tabs --type=angular
ionic start myApp blank --type=ionic1

其中,创建使用原生功能的项目,除了 Cordova 外,多了 Capacitor 的选择,此外,创建 Angular 版本 ionic4 项目的命令是这个(注意:带参数。不带参数创建的是 ionic3 项目)

ionic start myApp tabs --type=angular

当然也可以用 angular-cli 创建普通 Angular 项目,然后 npm 添加 @ionic/core 模块,创建完成后到目录结构如下图所示,它不再像 ionic3 那样封装了 angular 项目,而是直接就是一个 angular 项目,而且默认懒加载

二、配置和代理

v4angular 配置保持一致,可以在 angular.json 中进行一系列配置,代理则通过 proxy.config.json 配置

三、依赖变更

  • ionic-angular 引入变为了 @ionic/angular
  • rxjs 变化主要是由于 rxjs5.5 引入了 Pipeable Operator参考这里rxjs

四、css

  • angular 保持一致,采用 stylestyleUrls 方式引入,不再使用 page-**{} 方式
  • 全局样式:可以将 v3 中全局样式放置到 global.scss 中,也可以创建一个新的 scss 引入到 angular.json

五、路由差异

angular 路由官方文档 https://angular.cn/guide/router

也许 Ionic 4 中最显着的变化,以及需要对现有应用程序进行最大改变的变化,是转向 Angular 风格的路由。 Ionic 过去使用的典型 Push/Pop 风格导航仍然可用,您甚至可以直接通过 IonicWeb 组件使用这种导航方式,但推荐的方法是使用 Angular Router

观察目录结构,很容易发现这是一个 angular 项目,是因为它有一个 routing 模块

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: './tabs/tabs.module#TabsPageModule' }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

而对应的路由组件是 ion-router-outlet ,是对 Angularrouter-outlet 扩展,以兼容旧的导航方式,打开 tabs.page.html 可看到下面内容

  
    
  
  
    
  
  
    
  

而原来 ionic3 的生命周期函数由原来的

ionViewDidLoad
ionViewWillEnter
ionViewDidEnter
ionViewWillLeave
ionViewDidLeave
ionViewWillUnload
ionViewCanEnter
ionViewCanLeave

也相应做了调整,如

ionNavDidChange
ionNavWillChange
ionNavWillLoad

言外之意是,你既可以使用如下 Angular 方式做路由跳转

this.router.navigateByUrl('/login');
this.router.navigate(['/detail', { id: itemId }]);

也可以使用原有 Ionic 方式管控堆栈:

this.navCtrl.goForward('/route');
this.navCtrl.goBack('/route');
this.navCtrl.goRoot('/route');

前者注重 URL 管控,好处是灵活控制跳转的位置;后者注重代码管控,好处是它允许您指定导航的“方向”,这将有助于 Ionic 正确显示页面过渡。

六、生命周期

一些 Ionic 生命周期事件等同于 Angular 生命周期 hooks 。 例如, ionViewDidLoad() 扮演与 Angular OnInit 生命周期 hook(ngOnInit() )相同的角色。 在这种情况下,请使用 Angular 生命周期 hooks

七、懒加载

推荐使用 angular 路由的 loadChildren 方法实现

// v3 home.page.ts
@IonicPage({
  segment: 'home'
})
@Component({ ... })
export class HomePage {}

// home.module.ts
@NgModule({
  declarations: [HomePage],
  imports: [IonicPageModule.forChild(HomePage)]
})
export class HomePageModule {}

// v4 home.module.ts
@NgModule({
  imports: [
    IonicModule,
    RouterModule.forChild([{ path: '', component: HomePage }])
  ],
  declarations: [HomePage]
})
export class HomePageModule {}

// app.module.ts
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    RouterModule.forRoot([
      { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },
      { path: '', redirectTo: 'home', pathMatch: 'full' }
    ])
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

八、组件和指令的变更

Ionic 为了更通用化,把原来的指令调整为更通用标准的属性方式,如 icon-right 调整为 slot="end" , large 变成 size="large" ,