0%

Ionic Angular 组件 密码输入框组件

尝试在Ionic&Angular项目中创建一个密码输入框的组件。跟我们在移动端输入密码的行为类似,输入框的右侧有一个眼睛的图标,点击图标就可以显示或隐藏密码。

具体思路是,我们利用Angular的ng-content来讲输入框透传到组件里面,这样组件其实不用很关注输入框的东西,只需要关注交互就行了。关于内容投影以前也针对Angular写过一篇文章,可以参照:Angular ng-content 内容投影

创建组件

我们创建一个名为show-hide-password的组件:

1
$ ng g c show-hide-password

这个组件接受ion-input元素的透传,所以我们通过ContentChild来捕获这个元素:

1
@ContentChild(IonInput) input: IonInput;

我们需要一个变量来记录并控制密码的展示与否:

1
2
3
4
5
showPassword = false;
toggleShow() {
this.showPassword = !this.showPassword;
this.input.type = this.showPassword ? 'text' : 'password';
}

完整的show-hide-password.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import {Component, ContentChild, OnInit} from '@angular/core';
import {IonInput} from '@ionic/angular';

@Component({
selector: 'app-show-hide-password',
templateUrl: './show-hide-password.component.html',
styleUrls: ['./show-hide-password.component.scss'],
})
export class ShowHidePasswordComponent implements OnInit {
@ContentChild(IonInput) input: IonInput;

showPassword = false;

constructor() {
}

ngOnInit() {
}

toggleShow() {
this.showPassword = !this.showPassword;
this.input.type = this.showPassword ? 'text' : 'password';
}

}

然后看模板文件,我们需要一个ng-content来接受投影,然后需要一个眼睛的图标控制这个投影的元素:

1
2
3
4
5
<ng-content></ng-content>
<a class="type-toggle" (click)="toggleShow()">
<ion-icon class="show-option" name="eye-off-outline" [hidden]="showPassword"></ion-icon>
<ion-icon class="hide-option" name="eye-outline" [hidden]="!showPassword"></ion-icon>
</a>

相关样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:host{
display: flex;
width: 100%;
align-items: center;
.type-toggle{
padding-inline-start: 0.5rem;
}
.show-option, .hide-option{
font-size: 1.2rem;
display: block;
&:not(ion-icon) {
text-transform: uppercase;
font-size: 1rem;
}
}
}

组件这样基本就可以了。

应用组件

我们只需要在需要使用html中:

1
2
3
4
5
6
<ion-item>
<ion-label>密码</ion-label>
<app-show-hide-password>
<ion-input type="password" placeholder=""></ion-input>
</app-show-hide-password>
</ion-item>

这样就OK了。

真的 OK了吗?????

我们看下页面,嘎,只有input元素,没有眼睛。

再仔细看看,好像只渲染<ion-input>元素,<app-show-hide-passsword>简直就是个摆设,在app-show-hide-password.component.tscontructngOnInit函数里面打断点都没用,得,根本就没进组件。

再仔细回想下,为了方便管理,我把通用组件都放在了app/components/目录下,组件归属于components.module.ts。组件声明于一个module,应用于另一个module,那这这这???

在Angular里面已经不需要特意去entryComponents声明了啊,难道在ionic里面还需要?

得,加上吧。在包含组件的模块中需要导出组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ShowHidePasswordComponent} from './show-hide-password/show-hide-password.component';
import {IonicModule} from '@ionic/angular';

@NgModule({
declarations: [
ShowHidePasswordComponent,
],
imports: [
CommonModule,
IonicModule,
],
exports: [
ShowHidePasswordComponent
]
})
export class ComponentsModule {
}

在应用组件的模块需要在entryComponents里面声明组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ComponentsModule} from '../../core/components/components.module';
import {LoginComponent} from './login/login.component';
import {ShowHidePasswordComponent} from '../../core/components/show-hide-password/show-hide-password.component';
import {IonicModule} from '@ionic/angular';


@NgModule({
declarations: [
LoginComponent,
],
imports: [
CommonModule,
ComponentsModule,
IonicModule,
],
entryComponents: [
ShowHidePasswordComponent,
]
})
export class IndependenceModule {
}

再看页面预览:

show hide password

嗯,现在nice了。


Ionic中的angular和真正的Angular项目还是有点区别的,需要特殊对待。真闹心

码字辛苦,打赏个咖啡☕️可好?💘