Bootstrap

bmob Harmony快速开发手机号一键登录功能

最近用Bmob的鸿蒙SDK尝试了Harmony开发,做了一个几乎每个应用都会有的功能:手机号码+短信验证码一键注册登录的功能,感觉简直爽的不要不要的,ArkUI可见即可得的UI交互设计体验,配合Bmob后端云一如既往简单易用的风格,开发一些应用去占领鸿蒙市场。毕竟国产化是一个大的趋势,越早占坑越好。

先给一下效果图:

1.png

2.png

一、界面布局

1、添加状态装饰器

@State状态装饰器是鸿蒙ArKTS语言的一大特色。@State装饰的变量,又称为状态变量,可以和组件进行绑定渲染。当@State装饰的变量发生改变时,和这个变量绑定的UI的渲染也会发生改变。这样,我们的开发就可以变得非常松散耦合。

比如,下面的代码:

image.png

我们在按钮的点击事件中只需要设置message这个状态变量的值,和Text绑定的message就会立即渲染出来。

为了实现这个案例中的效果,我添加了如下的状态变量:

// 存储手机号码
@State
phone:string = ''

// 存储验证码
@State
code:string = ''

// 是否勾选了已阅读并同意用户协议和隐私政策
@State
isAgree:boolean = false

// 是否允许点击 获取验证码 按钮
@State
isAllowGetCOde:boolean = true

// 再次获取验证码倒计时(秒)
@State
count:number = 60

// 获取验证码按钮上的文字
@State
codeBtText:string = '获取验证码'

// 是否点击了 立即登录 按钮
@State
loading:boolean = false

2、布局和组件

这里用到了Image(图片)、Text(文本)、TextInput(输入框)、Checkbox(选择)、LoadingProgress(加载)组件,根据实际的情况,采用了Navigation(导航)、Scroll(滑动)、Column(行)、Row(列)布局。

我们可以在组件里面添加组件,比如下面的ArkUI代码,我们可以在按钮的组件中加上LoadingProgress组件和Text组件,实现更酷炫的效果。

Button({type:ButtonType.Normal}){
          Row(){
            if(this.loading){
              LoadingProgress()
                .color('#ffffff')
                .width(24)
                .height(24)
                .margin({right:10})
            }
            Text('立即登录').fontColor('#ffffff')
          }
        }

这个案例的布局和按钮UI代码如下:


Navigation(){
  Scroll(){
    Column(){
      Column(){
        Image($r("app.media.bmob"))
          .width(100)
          .aspectRatio(1)
          .borderRadius(10)

        Text('Bmob后端云')
          .fontSize(28)
          .margin({bottom:15,top:10})

        Text('Bmob后端云,让开发更简单')
          .fontSize(14)
          .fontColor('#979797')
      }

      Column({space:15}){
        TextInput({placeholder:'请输入手机号码',text:this.phone})
          .type(InputType.PhoneNumber)
          .onChange(val=>this.phone=val)

        Row({space:5}){
          TextInput({placeholder:'验证码',text:this.code})
            .type(InputType.Number)
            .layoutWeight(1)
            .showPasswordIcon(true)
            .onChange(val=>this.code=val)

          Button(this.codeBtText)
            .backgroundColor(this.isAllowGetCOde?'#fa711d':'#979797')
            .enabled(this.isAllowGetCOde)
            .width(100)
            .onClick(()=>{
              this.getCode()
            })
        }

        Row(){
          Checkbox()
            .selectedColor('#fa711d')
            .aspectRatio(1)
            .select(this.isAgree)
            .onChange((val)=>{
              this.isAgree=val
            })

          Row({space:4}){
            Text('已阅读并同意')
              .fontSize(14)
              .fontColor('#979797')
            Text('用户协议')
              .fontSize(14)
              .fontColor('#979797')
            Text('和')
              .fontSize(14)
              .fontColor('#979797')
            Text('隐私政策')
              .fontSize(14)
              .fontColor('#979797')
          }
        }
        .width('100%')

        Button({type:ButtonType.Normal}){
          Row(){
            if(this.loading){
              LoadingProgress()
                .color('#ffffff')
                .width(24)
                .height(24)
                .margin({right:10})
            }
            Text('立即登录').fontColor('#ffffff')
          }
        }
        .width('100%')
        .backgroundColor('transparent')
        .stateEffect(false)
        .borderRadius(4)
        .height(44)
        .linearGradient({
          direction:GradientDirection.Right,
          colors:[['#fc9c1c',0],['#fa711d',1]]
        })
        .enabled(!this.loading)
        .onClick(()=>{
          this.login()
        })
      }
      .padding(30)
    }
  }
}
.mode(NavigationMode.Stack)

我们可以在隐私政策和用户协议的Text中实现点击事件,这样就能够跳转到对应的内容阅读中。这也是我们为什么要把完整“已阅读并同意用户协议和隐私政策”拆分出来的原因。

二、添加交互代码

1、导入Bmob库

在 DevEco Studio 开发工具的命令行(Terminal)中执行下面的命令,安装Bmob Harmony SDK:

ohpm install @bmob/bmob 

如果一切顺利,你会在当前项目下的oh_modules目录下看到@bmob/bmob的包已经成功下载,如下图所示:

image.png

2、获取密钥

登录 Bmob后端云 ,创建应用,获取Secret Key和Secret Code,如下图所示:

image.png

3、初始化应用

在你创建的鸿蒙应用中,entry/src/main/ets 下面新建一个ArkTS File,名为BmobApp。代码如下:

import { Bmob } from '@bmob/bmob';
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class BmobApp extends AbilityStage {
    onCreate() {
        super.onCreate();
        Bmob.initialize('你的Secret Key', '你的Secret Code')
    }
}

4、配置网络权限和设置应用入口

打开 entry/src/main/module.json5 文件,在module节点下面新增 srcEntry 和 requestPermissions 子节点,配置如下:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "srcEntry": "./ets/BmobApp.ets",
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],
    ...省略更多
  }
}

image.png

5、编写获取短信验证码代码

获取短信验证码的代码,首先要先进行一些必要的数据验证。

为了防止用户拼命点击获取短信验证码的按钮,这里做了一个限制,当用户点击获取短信验证码之后,会有一个60秒的倒计时,倒计时结束,才能重新点击。

发送短信验证码的代码其实非常简单,就是调用Bmob.requestSmsCode()的方法,传递手机号码作为入口参数就可以轻松发送短信了。

整个发送短信验证码的事件代码如下:

getCode(){
  if(!this.phone)
    return promptAction.showToast({message:'请输入手机号码'})
  if(!this.isAgree)
    return promptAction.showToast({message:'请先同意用户协议和隐私政策'})

  this.isAllowGetCOde = false
  this.codeBtText = '重新获取(60)'

  Bmob.requestSmsCode(this.phone)
    .then((res)=>{
      promptAction.showToast({message:'发送成功'})

      // 限制60秒获取一次验证码
      this.timer = setInterval(()=>{
        this.count -= 1
        if(this.count<=0){
          clearInterval(this.timer)
          this.timer = -1
          this.isAllowGetCOde = true
          this.count = 60
          this.codeBtText = '获取验证码'
        } else{
          this.codeBtText = `重新获取(${this.count})`
        }
      },1000)
    })
    .catch((err)=>{
      this.isAllowGetCOde = true
      this.codeBtText = '获取验证码'
      promptAction.showToast({message:`获取验证码错误,原因:${err.error}`})
    })
}

6、手机号码+短信一键注册登录

这部分代码也是非常简单,首先进行必要的校验,然后执行Bmob.User().signOrLoginByMobilePhone()方法,传递手机号码和收到的验证码,即可实现一键注册登录。

login(){
  if(!this.phone)
    return promptAction.showToast({message:'请输入手机号码'})
  if(!this.code)
    return promptAction.showToast({message:'请输入验证码'})
  if(!this.isAgree)
    return promptAction.showToast({message:'请先同意用户协议和隐私政策'})

  this.loading = true
  // 调用Bmob后端云的手机号码一键登录的服务
  Bmob.User().signOrLoginByMobilePhone(this.phone,this.code)
    .then((res)=>{
      this.loading = false
      console.log('请求返回' + JSON.stringify(res));
      router.replaceUrl({
        url:'pages/Index'
      })
      promptAction.showToast({message:'注册成功'})
    })
    .catch((err)=>{
      promptAction.showToast({message:`发生错误,原因:${err.error}`})
    })
}

三、源码获取

https://gitee.com/zhang-ming-123/bmob-harmony-demo

四、参考资料

https://doc.bmobapp.com/data/harmony/index.html

;