# 17.6:用户登录

本节介绍一下用户登录功能,由于笔者条件有限,暂时没有设备实现网络请求操作,本节采用模拟网络请求的方式介绍一下用户信息和登录状态管理。

# 17.6.1:添加登录页面

用户登录页面简单比较简单,添加两个输入框和一个按钮,用户输入完用户名和密码后,点击登录按钮请求服务器,待服务器返回用户数据后,把用户数据存储在本地,用户下次打开APP后登录状态为已登录状态,登录页面代码如下所示:

import {TitleBar} from "../../common/widgets/titlebar"
import {ToastUtils} from "./../../common/utils/ToastUtils"
import {RouterUtils} from "./../../common/utils/RouterUtils"

import {HttpManager} from "./../../common/network/HttpManager"

@Entry @Component struct Login {

  build() {
    Column() {
      TitleBar({titleBarAttribute: {
        backShow: true,
        backCallback: () => {
          RouterUtils.back();
        },
        bgColor: "#f5890e",
        title: "登录"
      }})

      Row() {
        Text("用户名:")
          .fontSize(20)
          .height("100%")
          .width(80)

        TextInput()
          .fontSize(20)
          .height(40)
          .width(180)
      }
      .align(Alignment.Center)
      .margin({top: 60})
      .height(50)

      Row() {
        Text("密    码:")
          .fontSize(20)
          .height("100%")
          .width(80)

        TextInput()
          .fontSize(20)
          .height(40)
          .width(180)
          .type(InputType.Password)
      }
      .align(Alignment.Center)
      .height(50)

      Button({type: ButtonType.Normal}) {
        Text('登录')
          .fontSize(20)
          .fontColor(Color.White)
          .padding({left: 110, top: 5, right: 110, bottom: 5})
      }
      .margin({top: 50})
      .borderRadius(8)
      .backgroundColor($r("app.color.main_theme"))
      .onClick(() => {
        // 点击登录
      })
    }
    .width("100%")
    .height('100%')
  }
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

页面运行效果如下图所示:

17_6_1_1

# 17.6.2:更新登录状态

用户点击登录按钮开始进行登录操作,登录成功后通知其它页面变更登录状态,这里可以直接使用 @ohos.events.emitter 模块(不清楚该模块的使用可以阅读第十一章 第 2 节 的内容)提供的相关 API 实现,登录代码如下所示:

private login() {
  this.loadingDialogController.open();                  // 显示加载框
  HttpManager.getRequest().doPost("www.arkui.club", {   // 模拟网络请求
    callback: (data) => {                               // 请求回调
      this.loadingDialogController.close();             // 隐藏加载框
      if(data) {
        User.get()                                      // 更新用户信息
          .setId(data.id)
          .setName(data.name)
          .setToken(data.token)
          .setSkinType(data.skinType)
          .save();                                      // 保存用户信息
        Emitter.emit({ eventId: Constant.USER_LOGIN }); // 发送消息
        ToastUtils.show("登录成功");
        RouterUtils.back();                             // 返回上一页面
      } else {
        ToastUtils.show("登录失败");
      }
    }
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

用户点击登录按钮的时候,首先弹出一个 loading 框,登录成功后隐藏登录框,然后更新 User 信息并操作信息,接着调用 Emitteremit() 方法发送一个消息,通知相关界面做更新操作,这里笔者直接使用 Emitter 方式,读者也可以参考第二章 第 5 节 介绍的全局状态实现此功能。

Emitter 发送消息后,在设置页面接收效果并更新 UI ,代码如下所示:

@Entry @Component struct Settings {

  @State user: User = User.get(); // 状态变更

  build() {
    Column() {
      TitleBar({titleBarAttribute: {
        backShow: true,
        backCallback: () => {
          RouterUtils.back();
        },
        bgColor: "#f5890e",
        title: ""
      }})
      Column({space: 10}) {
        Image($r("app.media.icon_avatar"))
          .size({width: 70, height: 70})
        Text(this.user.logined() ? ("ID: " + this.user.getId()) : "游客")
          .fontSize(20)
          .fontColor("#ffffff")
      }
      .width("100%")
      .backgroundColor($r("app.color.main_theme"))

      Text()
        .width(1)
        .height(30)

      SettingItem({topLine: true, text: this.user.logined() ? "登出" : "登录", bottomLine: true, callback: () => {
        if(this.user.logined()) {

        } else {
          RouterUtils.open("pages/setting/login");
        }
        ToastUtils.show("login")
      }})
    }
    .width("100%")
    .height('100%')
  }

  aboutToAppear() {
    // 订阅消息
    Emitter.on({
      eventId: Constant.USER_LOGIN
    }, (data) => {
      this.user = User.get();
    });
  }

  aboutToDisappear() {
    // 取消订阅
    Emitter.off(Constant.USER_LOGIN);
  }
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

Settings 页面订阅了 Emitter 的消息,当首到指定消息时主动更新 User 信息就可以触发 build() 方法,就实现了页面的刷新。

# 17.6.3:登录效果演示

以上就是登录页面实现的主要流程,由于预览器对于数据存储和网络请求以及 Emitter 不支持的缘故,笔者是模拟运行效果,待后续有设备后,笔者再补充完整的运行效果图。模拟运行效果如下图所示:

17_6_1_1
(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2