ionic 学习笔记

405 阅读4分钟

1.安装环境

在使用ionic之前,先安装ionic的环境

npm install -g ionic
npm install -g cordova 
npm install -g @ionic/cli

如果以前安装了ionic cli,由于程序包名称的更改,需要将其卸载。

npm uninstall -g ionic
npm install -g @ionic/cli

创建一个ionic app

ionic start

也可以这个样子创建

ionic start photo-gallery tabs --type=angular --capacitor

将ionic app运行起来,可以在浏览器中打开

ionic serve

2.目录结构

通过ionic cli 创建一个app,整个项目的目录结构如下:

1636014312.jpg

下一步就可以开始构建功能和组件。大部分应用将在src/app/目录中开发。 1636014455(1).jpg

src目录包含index.html文件、测试配置文件、图像的资产文件夹以及应用程序代码的app目录等项目。 1636014606(1).jpg src/app包含根应用程序组件和模块,以及包含应用程序功能(如页面、组件、服务等)的附加目录。

3.生命周期

  1. ionic page的生命周期
    • ionViewDidLoad 当页面已经载入后,这个事件仅当页面被创建时执行一次。如果一个页面离开,但是已经缓存,那么后续的查看也不会触发。当为某个页面设置代码时,可放在该方法里。
    • ionViewWillEnter 当页面将要进入并变成激活页面时触发。
    • ionViewDidEnter 当页面已经进去并激活了,不管它是否是第一次载入还是一个缓存的页面,该事件都触发。(此处可以去做页面的第一次请求)
    • ionViewWillLeave 当页面将要离开,将不再是一个激活的页面时触发。
    • ionViewDidLeave 当页面已经离开,不是一个激活页面时触发。
    • ionViewWillUnload 当页面将要销毁并移除其元素时触发。
    • ionViewCanEnter 在视图可以进入之前运行。 这可以在经过身份验证的视图中用作一种“保护”,您需要在视图可以进入之前检查权限。
    • ionViewCanLeave 在视图可以离开之前运行。 这可以在经过身份验证的视图中用作一种“保护”,您需要在视图离开之前检查权限。
  2. angular的生命周期
    • ngOnChanges() 当Angular(重新)设置数据绑定输入属性时响应。当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前。
    • ngOnInit() 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮ngOnChanges()完成之后调用,只调用一次。(可以初始化数据)
    • ngDoCheck() 检测,并在发生Angular无法或不愿意自己检测的变化时作出反应。在每个Angular变更检测周期中调用,ngOnChanges()和ngOnInit()之后。
    • ngAfterContentInit() 当把内容投影进组件之后调用。第一次ngDoCheck()之后调用,只调用一次。(只适用于组件)
    • ngAfterContentChecked() 每次完成被投影组件内容的变更检测之后调用。ngAfterContentInit()和每次ngDoCheck()之后调用。(只适用于组件)
    • ngAfterViewInit() 初始化完组件视图及其子视图之后调用。第一次ngAfterContentChecked()之后调用,只调用一次。(只适用于组件)
    • ngAfterViewChecked() 每次做完组件视图和子视图的变更检测之后调用。ngAfterViewInit()和每次ngAfterContentChecked()之后调用。(只适用于组件)
    • ngOnDestroy 当Angular每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。在Angular销毁指令/组件之前调用。

4.路由,页面跳转方式

  1. 路由跳转页面

    <ion-item routerLink="/跳转的页面" [queryParams]="{name:zhang}">
    	页面跳转
    </ion-item>
    
    // 使用NavController
    import { NavController } from '@ionic/angular';
    
    constructor(private navCtrl: NavController){}
    
    jump(){
        this.navCtrl.navigateForward('跳转的页面',{queryParams: { name: 'zhang' }} )
    }
    
    // 使用router
    import { Router } from '@angular/router';
    
    constructor(private router: Router){}
    
    jump(){
        this.router.navigate(['跳转的页面'], {
     		queryParams: { name: '李' },
     	});
    }
    
  2. 返回上一 个页面

    // 使用NavController
    import { NavController } from '@ionic/angular';
    
    constructor(private navCtrl: NavController){}
    
     back(){
     	// 基于路径的历史纪录返回的,他在后退的时候根据上一个打开的页面返回   
        this.navCtrl.back()
     }
    
    pop(){
        // 基于路由层级进行后退
        this.navCtrl.pop()
    }
    
    // 使用router
    import { Router } from '@angular/router';
    
    constructor(private router: Router){}
    
    back(){
        // 返回到指定页面,严格点说是基于返回的动画执行的打开页面的操作
        this.router.navigateByUrl('返回的页面')
    }
    
  3. 接受路由参数

    import { ActivatedRoute } from '@angular/router';
    
    constructor(private navParam: ActivatedRoute){}
    
    // 获取url参数 ?xx=xx&xx=xx
    getQueryParams(){
    	// 同步获取
    	console.log(navParam.snapshot.queryParams);
     	// 异步获取
        navParam.params.subscribe(param => {
            console.log(param);
        })
    }
    
    // 获取参数 /xx
    getParams(){
        console.log(navParam.snapshot.params);
    }
    
  4. 使用ion-modal创建页面

    public static async createModalDialog(pageName: string, modalCtrl: ModalController, props: {} = null, options: {} = null, cssClass: string = "") {
            //'hello',  'hellos/hello', 'hellos/hello-world'
            if (pageName.startsWith('/')) {
                pageName = pageName.substr(1);
            }
            let pagefileName = pageName.substr(pageName.lastIndexOf('/') + 1);
            let pagePascalName = this.toPascalCase(pagefileName);
            pageName += (pageName.startsWith('.') ? '' : '/') + pagefileName;
            await import((pageName.startsWith('.') ? "" : "./pages/") + pageName + ".module").then(m => m[pagePascalName + 'PageModule']);
            let page = await import((pageName.startsWith('.') ? "" : "./pages/") + pageName + ".page").then(m => m[pagePascalName + 'Page']);
    
            let modalOpts = {
                component: page,
                componentProps: {
                    'isModalDlg': true
                },
                showBackdrop: true,
                backdropDismiss: true,
                cssClass: cssClass,
                //id:'123',
                swipeToClose: true,
                keyboardClose: false
            };
            if (props) {
                Object.assign(modalOpts.componentProps, props);
            }
            if (options) {
                Object.assign(modalOpts, options);
            }
    
            let modal = await modalCtrl.create(modalOpts);
            return modal;
        }
    
    // 方法调用
    fn(){
        let model = await createModalDialog('跳转的页面', this.modalCtrl,{},{ enterAnimation: ScaleAnimation.enter, leaveAnimation: ScaleAnimation.leave});
        // 返回一个promise,该promise在模态消失时得到解决。
        model.onDidDismisee.then((res)=>{
         	//进行操作   
        })
        modal.present();
    }
    

5.组件传值

父组件==>子组件

// parent.ts
public parentVal = '我是父组件的值'
// parent.html
<child [parentVal]="parentVal"></child>
// child.ts
import { Component, Input } from '@angular/core';

// 接受父组件的值
@Input() parentVal: any

子组件==>父组件

// child.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Output fromChild = new EventEmitter();
transmit() {
    this.fromChild.emit('我是从子组件来的');
}

// child.html
<ion-button (click)="transmit()"> 传值给父组件 </ion-button>
// parent.html
<child (fromChild)="receiveVal($event)"></child>

// parent.ts
receiveVal(e) {
	console.log(e); // 我是从子组件来的
}