ionic3 实现判断登录状态,实现登录和注销功能

这篇文章原来是转载的,因为里面有些代码在实际应用上有些出入。笔者在这里进行了改良更新,所以标记为了原创。

1. 创建页面

创建一个登录页面

$ ionic g page login

2. 引入和声明

在 app.modules.ts中引入LoginPage,并在声明组件declarations、entryComponents中添加 LoginPage

import { LoginPage } from  '../pages/login/login';

3. 设置根页面

在app.components.ts页面 引入LoginPage, 设置loginPage为首次显示页面 

import  { LoginPage } from  '../pages/login/login';

export class MyApp {
  rootPage = LoginPage;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

4. 生成login页面

login.html

<ion-header>
  <ion-navbar>
    <ion-title>登录</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-item>
    <ion-label fixed>账号</ion-label>
    <ion-input type="text" placeholder="请输入账号" #username></ion-input>
  </ion-item>
  <ion-item>
    <ion-label fixed>密码</ion-label>
    <ion-input type="password" placeholder="请输入密码" #password></ion-input>
  </ion-item>
  <ion-item no-lines>
    <label item-right>记住密码</label>
    <ion-toggle></ion-toggle>
  </ion-item>

  <div style="text-align: center; margin-left: 30px; margin-right: 30px;">
    <button ion-button block color="danger" (click)="logIn(username, password)">
      登录
    </button>
  </div>
</ion-content>

login.ts

利用 LocalStorage 存储登录状态,假设用户名为 test,密码为 123456,当两者匹配时,将用户名存储到 Storage 中,并跳转到 Tabs 页面。如果有对接服务器数据请求,那么这块可以换为向服务器提交登录,并且将服务器返回的值存入Storage,服务器这块在这里就不讲解了。

扫描二维码关注公众号,回复: 10512691 查看本文章
logIn(username: HTMLInputElement, password : HTMLInputElement) {
  if(username.value.length > 0) {
      console.log(username.value);
  }
  if(password.value.length > 0 ) {
    console.log(password.value);
  }
  if(username.value == 'test' && password.value == '123123') {
    window.localStorage.setItem('username',username.value); //保存登录时数据
    this.navCtrl.setRoot(TabsPage); //跳转到登录后的页面
  }
}

为什么用 setRoot 而不是 push?

在之前NavController 的 push 方法跳转页面,为何这里使用的却是另一个方法 setRoot 呢?因为这两种方法的原理不同,push是将新页面推送到页面栈中,新页面可以 pop 回旧页面;而 setRoot 是将原有的根页面替换成新页面,相当于换了一个新的页面栈,原有的页面已经被回收掉了,这时候新页面是无法 pop 回旧页面的。

在界面表现上,如果是通过 push 进 Tabs 页面,可以通过 Android 设备上的返回按钮回到登录页面,这显然不符合我们的操作逻辑。

5.  在首页提取 Storage 的数据

home.html

<ion-content padding>
  登录名称:{{username}}
  <br>
  <button ion-button (click)="goNews()">跳转到新闻页面</button>
  <br>
  <button ion-button (click)="logout()">退出</button>
</ion-content>

home.ts 获取 Storage 的数据

public username:string;

constructor(public navCtrl: NavController) {

}

ionViewWillEnter(){
  this.username= window.localStorage.getItem('username');
}

之后展示为:

6. 利用登录状态进行页面跳转

在测试过程中,你会发现,浏览器的每次刷新都要重新登录。这时,就需要修改在此修改 app.component.ts 添加一个钩子:判断 Storage 中存在 username 与否,定义不同的 rootPage ,再刷新页面可以发现,APP 直接进入首页了。

export class MyApp {
  rootPage:any;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    if(window.localStorage.getItem('username')) {
      this.rootPage = TabsPage;
    } else {
      this.rootPage = LoginPage;
    }
    platform.ready().then(() => {
      ...
    });
  }
}

7. 退出登录

清除 Storage 中的用户信息

注意:

这里说一下,原文用的是navCtrl做的根导航设置,比如这样:

logout() {
  window.localStorage.removeItem('username');
  this.navCtrl.setRoot(LoginPage);
}

这会出现一个问题:

导航到根组件LoginPage后底部tab仍然存在,如果用一些技术手段将tab隐藏也可以做到,但是当隐藏后继续点击登录以后,会发现虽然页面已经到了tab的第一个页面,但是tab的焦点还在User的选项卡上面(我的项目和现在的文章有些不一样,我项目的登出不在首页,所以登录后设置的根组件并不是触发退出登录的页面,这就发生了这个问题),后面我换了另一个方法来解决这个问题:

this.app.getRootNav().setRoot(LoginPage);

但是,ionic提示我getRootNav()方法即将启用,那么我就在国外论坛上面找另一个替代方法

那就是这个:

this.app.getRootNavs()[0].setRoot(LoginPage);

这里特别强调这一点,因为ionic团队是不断发展的,随着你ionic版本的升级,一些方法即将面临废弃,那么就要用这个新的来代替。

那么,这里的代码就是这样写:

logout() {
  window.localStorage.removeItem('username');
  this.app.getRootNavs()[0].setRoot(LoginPage);
}

8. 其他

  • LocalStorage 的数据是没有过期时间的,只要它没有被删除,就会永久地储存在 Storage 中。如果你希望数据在一定时间内失效,可以使用 SessionStorage 来替代。
  • LocalStorage 和 SessionStorage 的存储空间只有 5MB,请不要存储大量的数据。
  • 在新版 iOS 中,LocalStorage 可能会在系统清理内存时被清除,在 Android 中也可能发生 LocalStorage 被清除的情况。如果你需要更好地存储方案,可以考虑使用 SQLlite 来替代。
发布了9 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_29971465/article/details/88033505