猫窝私语 — Makumo's Blog

玛酷猫的温馨小窝,记录生活点点滴滴。

@玛酷猫5 年前

01/10
14:39
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)

接下来就是页面的迁移,先用命令创建原来项目对应的页面,例如登录页面

ionic g page pages/signIn

这是会在src/app/pages目录下面生成sign-in文件夹,里面包含5个文件,相对于Ionic3,除了文件名命名有些许区别外,同时还多了一个测试文件,对比下Ionic3的sign-in.ts和4的sign-in.page.ts文件的主体结构

# ionic3
import { Component, OnInit } from '@angular/core';
@IonicPage({
  segment: 'sign-in'
})
@Component({
  selector: 'page-sign-in',
  templateUrl: 'sign-in.html',
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

# inoic4
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
  selector: 'app-sign-in',
  templateUrl: './sign-in.page.html',
  styleUrls: ['./sign-in.page.scss'],
  encapsulation: ViewEncapsulation.None
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

整体上差别不大,主要区别在@Component部分,选择器的命名,模板文件和样式文件的引用,3中的@IonicPage部分在4种移除,部分功能被放在Angular的路由中。此外特别提下encapsulation: ViewEncapsulation.None的问题,这部分我也没完全弄明白,大概理解是Ionic4使用了标准的Web Components,可以在页面上看到大量的shadow-dom,默认情况下,由于Angular提供的样式包装机制来封装组件,使得组件的样式不受外部影响,就是说无法修改组件的样式,所以这里要将封装模式调整成none,以便于修改组件的样式,详细说明请参考官方文档,传送门。此外由于使用标准Web Components,样式也要大量的使用CSS4 Variables的写法。

页面生命周期

在Ionic3中,常用的页面生命周期函数有下面6种

  • ionViewDidLoad 当页面加载的时候触发,仅在页面创建的时候触发一次,如果被缓存了,那么下次再打开这个页面则不会触发
  • ionViewWillEnter 当将要进入页面时触发
  • ionViewDidEnter 当进入页面时触发
  • ionViewWillLeave 当将要从页面离开时触发
  • ionViewDidLeave 离开页面时触发
  • ionViewWillUnload 当页面将要销毁同时页面上元素移除时触发

在Ionic4中,使用Angular的生命周期函数,具体ionViewDidLoad被ngOnInit替代,ionViewCanEnter和ionViewCanLeave被路由守卫替代,其他的暂时可以正常使用,不过可能在以后的版本中被其他用法做代替。

组件的标准化

由于使用Web Components标准,很多组件和属性的写法也发生变化,譬如

// ionic 3
<button type="button" ion-button clear small icon-start (click)="findPassword()" class="option-password">忘记密码</button>

<ion-list radio-group no-lines [(ngModel)]="schoolCode">
  <ion-item *ngFor="let s of schools">
    <ion-avatar item-start><img src="{{s.logo}}"></ion-avatar>
    <ion-label>{{s.name}}</ion-label>
    <ion-radio value="{{s.code}}"></ion-radio>
  </ion-item>
</ion-list>

// ionic 4
<ion-button type="button" fill="clear" size="small" (click)="findPassword()" class="option-password">忘记密码</ion-button>

<ion-list lines="none">
  <ion-radio-group [(ngModel)]="schoolCode">
    <ion-item *ngFor="let s of schools">
      <ion-avatar solt="start"><img [src]="s.logo" alt=""></ion-avatar>
      <ion-label>{{s.name}}</ion-label>
      <ion-radio [value]="s.code"></ion-radio>
    </ion-item>
  </ion-radio-group>
</ion-list>

除了button标签替换成ion-button以外,很多属性也发生变化,譬如button的所有属性都进行了更换,clear更换成fill=“clear”等,其他标签的属性,譬如item-start更换为solt=“start”,此外类似radio-group的用法也发生大变化。由于不少用法发生变化,具体还是对应着官方文档进行迁移,传送门

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)