05 定时器,延时器、递归、内置对象(Object 对象+Math 对象+Date 对象+String对象)
一、定时器,延时器
1.1. setTimeout延时器
@Entry
@Component
struct Page01_timeoutAndInterval {timeId?: numberbuild() {Column({ space: 20 }) {Text('延时器-Timeout').fontSize(30).width('100%').textAlign(TextAlign.Center)Row({ space: 20 }) {Button('开启延时器').onClick(() => {// 开启延时器let timeId = setTimeout(() => {// 延迟执行逻辑console.log('代码执行啦')}, 2000)// 保存定时器 idthis.timeId = timeId})Button('关闭延时器').onClick(() => {// 调用 clearTimeout 清除定时器clearTimeout(this.timeId)})}}.padding(10)}
}
1.2. setInterval定时器
// 1. 基本使用
setInterval(()=>{// 延迟执行的逻辑
},时间)// 2. 获取返回的定时器 id
const timeId = setInterval(()=>{// 延迟执行的逻辑
},时间)// 3. 根据定时器 id 清除定时器
clearInterval(timeId)
1.3例demo:获取验证码
@Entry
@Component
struct LoginDemo {//定义状态变量 通过变量控制文字的显示和隐藏@State isShow:boolean=false//1,定义状态变量存储倒计时 时间@State time:number=3//定时器的id返回值存储timer:number=0build() {Column() {this.titleBuilder()TextInput({ placeholder: '请输入手机号' }).textInputExtend()Divider()Row() {TextInput({ placeholder: '请输入验证码' }).textInputExtend().layoutWeight(1)Text(this.isShow?`${this.time}秒后获取`:'发送验证码')/*倒计时效果 -> 数字减减/如果时间小于0,显示"发送验证码"/倒计时结束,弹框显示随机的4位验证码1.定义状态变量,存储倒计时时间2、开启定时器,在定时器中,将数字进行减减3,判断,如果时间小于0,清除定时器更改文本内容(改状态变量值)时间重置弹框显示随机验证码*/.fontSize(14).fontColor(Color.Gray).onClick(()=>{//问题-->点击多次,会有多个定时器开启,所有开启的定时器都会执行//解决 -> 原则是只保留一个开启的定时器//步骤:1,判断是否有定时器开启 2,如果有定时器开启,就不需要再开启定时器了if(this.timer!=0){//说明有定时器开启了//解决方式一 清除定时器clearInterval(this.timer)//解决方式二 return(下面的代码不再执行)但需要把timer的值重置return}this.isShow=true//开启定时(间隔的不断执行)器,进行减减this.timer=setInterval(()=>{// 2、开启定时器,在定时器中,将数字进行减减this.time--//3,判断,如果时间小于0,if (this.time<0) {//3.1清除定时器clearInterval(this.timer)//3.2更改文本内容(改状态变量值)this.isShow=false//3.3时间重置this.time=3//3.4弹框显示随机验证码AlertDialog.show({// 求任意区间随机整数的公式//Math.floor(Math.random() * (最大值-最小值 + 1) + 最小值)message:` ${Math.floor(Math.random()*(9999-1000+1)+1000)}`})//点击多次,会有多个定时器开启(解决方法二return下面的代码不再执行 重置timer)
this.timer=0}},1000)//在这个位置判断-->错误//定时器和延时器是异步代码(不会立刻执行的代码)//代码执行,是先执行同步代码,然后在执行异步代码(延时器/定时器/数据请求/事件)})}.width('100%')Divider()Button('登录').width('100%').type(ButtonType.Normal).backgroundColor('#ea6051').margin({ top: 50 })}.padding({ top: 80, left: 40, right: 40 }).width('100%').alignItems(HorizontalAlign.Start)}@BuildertitleBuilder() {Text('短信登录').fontSize(25).fontWeight(600).margin({ bottom: 30 })}
}@Extend(TextInput)
function textInputExtend() {.backgroundColor(Color.White).padding({ left: 0, top: 20, bottom: 20 }).placeholderColor('#ccc')
}
二、递归
递归近似于循环避免无限循环,或者在这种情况下更确切地说是无限递归
三、内置对象
Object 对象
//Object.keys 方法interface Person {name:stringage:20
}let ym:Person = {name:'杨幂',age:20
}
console.log(``,JSON.stringify(Object.keys(ym))) // ["name","age"]//Object.values方法interface Person {name:stringage:20
}let ym:Person = {name:'杨幂',age:20
}
console.log(``,JSON.stringify(Object.values(ym))) // [ ["杨幂",20]
Math 对象
常用属性
Math.pi
圆周率,一个圆的周长和直径之比,约等于 3.14159。
console.log(Math.PI.toString())
常用方法
Date 对象
例:demo 倒计时功能的实现
1. 定义状态变量
声明三个状态变量hh
、mm
、ss
,分别用于存储倒计时的时、分、秒
类型设为number|string
,初始值均为10
@State hh:number|string = 10 @State mm:number|string = 10 @State ss:number|string = 10
2. 实现倒计时核心逻辑(getTime函数)
获取时间戳:
获取当前时间戳:
let now = Number(new Date())
获取目标时间戳
(设定为2025-8-12 17:00:00)let end = Number(new Date('2025-8-12-17:00:00'))
计算时间差:
计算两个时间戳的差值:let time = end - now
转换为时分秒:
计算小时:Math.floor(time/1000/60/60%24)
计算分钟:Math.floor(time/1000/60%60)
计算秒钟:Math.floor(time/1000%60)
补零处理:
对小于10的数字前面加0:h = h < 10 ? '0' + h : h
(时分秒均做相同处理)
更新状态变量:
将处理后的时分秒分别赋值给this.hh
、this.mm
、this.ss
3. 启动定时器
在UI组件的onAppear
生命周期中启动定时器
每1000毫秒(1秒)调用一次getTime
函数更新倒计时
.onAppear(()=>{setInterval(()=>{this.getTime()},1000) })
4. 展示倒计时
在页面中通过
Text
组件展示hh
、mm
、ss
的值使用
@Extend
扩展Text组件样式,统一设置倒计时数字的展示样式将三个时间数字横向排列,形成完整的倒计时显示
实现要点总结
利用时间戳差值计算剩余时间
通过定时器每秒更新一次倒计时状态
对单个数字进行补零处理,保证显示格式统一
使用状态变量实现数据驱动UI更新
利用组件生命周期函数在页面加载时启动倒计时
@Entry
@Component
struct Date01 {// 需求1: 获取年月日 星期getDay(){// 实例化日期对象const date:Date = new Date()// 格式化日期const y:number = date.getFullYear()const m:number = date.getMonth() + 1const d:number = date.getDate()// 格式化星期const day:number = date.getDay()// 将星期的数字转为文字let week:string = ''switch (day) {case 0:week = '星期日'breakcase 1:week = '星期一'breakcase 2:week = '星期二'breakcase 3:week = '星期三'breakcase 4:week = '星期四'breakcase 5:week = '星期五'breakdefault:week = '星期六'}return `${y} 年 ${m} 月 ${d} 日 ${week}`}// 倒计时/*** 距离时间点的倒计时 - 18:30:00* 1. 定义状态变量,存储时分秒* 2. 封装成函数, 业务写到函数中* - 获取70年到现在的时间戳* - 获取70年到未来的时间戳* - 获取时间戳的差值* - 将时间戳转为时分秒* - 将时分秒赋值给状态变量* 3. 页面加载时,开启定时器,调用函数*/@State hh:number|string = 10@State mm:number|string = 10@State ss:number|string = 10getTime(){// 获取现在的时间戳let now = Number(new Date())// 获取未来的时间戳let end = Number(new Date('2025-8-12-17:00:00'))// 获取差值let time = end - nowtype IType = string|number// 转为时分秒let h:IType = Math.floor(time/1000/60/60%24) // 时let m:IType = Math.floor(time/1000/60%60) // 分let s:IType= Math.floor(time/1000%60) // 秒// 补零操作 -> 数字如果是小于10 在数字的前面加0 例如: 9 -> 0 + 9 -> 09h = h < 10 ? '0' + h : hm = m < 10 ? '0' + m : ms = s < 10 ? '0' + s : s// 赋值给状态变量this.hh = hthis.mm = mthis.ss = s}build() {Column() {Column() {Text(this.getDay()).fontColor(Color.White).fontSize(20)Stack() {Row({ space: 10 }) {Text(this.hh.toString()).textStyle()Text(this.mm.toString()).textStyle()Text(this.ss.toString()).textStyle()}.onAppear(()=>{// 页面加载时触发事件setInterval(()=>{this.getTime()},1000)})Divider().strokeWidth(2).color(Color.Black)}.padding(10)Text('Stay hungry,Stay foolish').fontColor(Color.White).fontSize(18)}}.width('100%').height('100%').backgroundColor(Color.Black).justifyContent(FlexAlign.Center)}
}@Extend(Text)
function textStyle() {.width(100).height(100).backgroundColor('#191919').borderRadius(10).textAlign(TextAlign.Center).fontColor(Color.White).fontSize(70).fontWeight(900)
}
String对象
includes 方法
includes 方法 判断是否存在特定字符
字符串.includes(要查找的内容,开始查找的下标)
在一个字符串中找另一个字符串返回值true/false
// includes 方法 判断是否存在特定字符
// 语法:
// 字符串.includes(要查找的内容,开始查找的下标) 在一个字符串中找另一个字符串返回值true/false
// 0.判断
const demo='鸿蒙开发'
console.log(``,demo.includes('鸿蒙',3))//false
// 1. 判断是否有@符号
const emailStr = 'user@example.com'
console.log(``,emailStr.includes('@'))//true// 2.判断是否为gif文件
const fileName = 'dance.gif'
console.log(``,fileName.includes('png'))//false
// 3.判断密码中是否有下划线
const pass = 'itheima-123'
console.log(``,pass.includes('_'))// 4.判断是否有特定词汇 ,比如 牛逼 最 等
const comment = `杭州是一个令人惊叹的地方,值得一游的地方!`
console.log(``,comment.includes('xxx'))//false
slice(始标,束标) ,截取字符串
语法:字符串.slice(开始下标,结束下标) 截取字符串 返回截取到的字符串
// slice方法(如果只写开头下标,不写结尾下标,会默认从起始索引切割到末尾)
// 语法:字符串.slice(开始下标,结束下标) 截取字符串 返回截取到的字符串// slice方法(如果只写开头下标,不写结尾下标,会默认从起始索引切割到末尾)
// 1. 提取 逗号 之后的内容
const str1 = 'hi,你好吗'
console.log(``,str1.slice(3,))// 你好吗
split('分隔符') 字符串转为数组
split('分隔符')字符串转为数组 返回值数组
//字符串转数组——语法:字符串.split('分隔符')将字符串转为数组 返回值数组
// 1. 切割为数组
const branchFilter: string = ' 全部分路 | 对抗路 | 中路 | 发育路 | 游走 | 打野 '// 2. 获取日期
const dateStr:string = '2024-04-27'console.log(``,JSON.stringify(branchFilter.split('|')))// [" 全部分路 "," 对抗路 "," 中路 "," 发育路 "," 游走 "," 打野 "]
console.log(``,JSON.stringify(dateStr.split('-')))// ["2024","04","27"]
trim 去除两边空格
// trim 去除两边空格
// 1.基础文本
const str: string = ' 123 '
// 2.用户名
const username = ' jack '
// 3.密码
const password = ' 1234abc '
字符串转大小写
// 1.字符串.toLowerCase() 字符串转小写 返回新字符串
// 2.字符串.toUpperCase() 字符串转大写 返回新字符串
// 语法:
// 1.字符串.toLowerCase() 字符串转小写 返回新字符串
// 2.字符串.toUpperCase() 字符串转大写 返回新字符串// toLowerCase 转小写 toUpperCase 转大写
// 1.验证码
const code = '1a2C'
console.log(``,code.toLowerCase())// 1a2c
// 2.带后缀名的文件信息
const filename = 'abc.PNG'
console.log(``,filename.toUpperCase())//ABC.PNG
// 3.编程语言中的关键字
const boolStr = 'true'
console.log(``,boolStr.toUpperCase())//TRUE