1 判断
ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。
@Entry
@Component
struct LearnIf {
@State isShow: boolean = false
build() {
Column() {
Button(this.isShow ? '消失' : '显示').onClick(() => {
this.isShow = !this.isShow
})
if (this.isShow) {
Text('哈哈我出现了')
}
}
}
}
- 切换显示不同组件
2 循环
为啥要有循环 =》 服务器返回数据 一般都是 数组里面是一个个对象 咱们需要通过循环挨个展示 v-for
ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件
数组.forEach( (item,i)=>{} )
ForEach( 数组, (item,i)=>{ 布局代码内置组件或者自定义组件 }, ㊙️ )
ForEach(
arr: Array,
itemGenerator: (item: any, index?: number) => void,
keyGenerator?: (item: any, index?: number) => string
)
基本使用
@Entry
@Component
struct Index {
@State arr:string[] = [
'one',
'two',
'three',
]
build() {
Column() {
ForEach(
this.arr,
(item:string) => {
Row() {
Text(item)
}
}
)
}
}
}
key
在ForEach循环渲染过程中,系统会为每个数组元素生成一个唯一且持久的键值,用于标识对应的组件。当这个键值变化时,ArkUI框架将视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。
ForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即
(item: any, index: number) => { return index + '__' + JSON.stringify(item); }
- 情况1
@Entry
@Component
struct Index {
@State arr:string[] = [
'one',
// temp
'two',
'three',
]
build() {
Column() {
Button('追加').onClick(() => {
this.arr.splice(1, 0, 'temp');
})
ForEach(
this.arr,
(item:string) => {
Row() {
Text(item)
}
},
// (item, i) => 返回值
(item, i) => i.toString()
)
}
}
}
- 情况2
@Entry
@Component
struct Index {
@State arr:string[] = [
'one',
'two',
'three',
]
build() {
Column() {
Button('追加').onClick(() => {
this.arr.splice(1, 0, 'three');
})
ForEach(
this.arr,
(item:string) => {
Row() {
Text(item)
}
},
// (item, i) => 返回值
(item) => item
)
}
}
}
百度热搜
@Entry
@Component
struct Index {
@State news: any[] = [
{id:1, title: '第十个国家公祭日', hot: true},
{id:2, title: '关键时刻 中央开了一', hot: false},
{id:3, title: '红斑狼疮致残致死率', hot: true},
{id:4, title: '专家:房贷利率还有下', hot: false},
]
// fontColor = 数据
// fontColor = function() {}
fontColor = (id) => {
let color = '#9396a0'
if (id==1) color = '#FE2D46'
if (id==2) color = '#F60'
if (id==3) color = '#FAA90E'
return color
}
build() {
Column({space: 20}) {
// 标题
Row() {
Text('百度搜索')
.fontSize(45)
.fontWeight(FontWeight.Bold)
}
.width('100%')
// 筛选按钮
Row() {
Button('热搜榜')
.type(ButtonType.Normal)
Button('北京榜')
.type(ButtonType.Normal)
.margin({left:20})
.fontColor('#000')
.backgroundColor('#f5f6fa')
}
.width('100%')
// 搜索列表
ForEach(
this.news,
(item: any) => {
Row() {
Text(String(item.id))
.fontSize(30)
.fontColor(this.fontColor(item.id))
.fontWeight(FontWeight.Bold)
Text(item.title)
.fontSize(30)
.padding({left:5})
if (item.hot) {
Text('热')
.fontColor('#fff')
.backgroundColor('#e0773e')
.padding(4)
.borderRadius(5)
}
}
.width('100%')
}
)
}
.padding(20)
}
}
鸿蒙计算器
# 计算器思路
一、布局
Column
Row结果
Row四个文字按钮 每个文字w75/h75/圆角
...
也可以进一步完善 文字按钮定义成数组,循环展示
二、声明状态 num1/fuhao/num2/result => 并视图展示所有装填
三、绑定点击事件 onResult
四、处理函数中线保存num1、再保存fuhao、接着num2、最后AC、=
if (data === '=') {
let sum:number = 0
switch (this.fuhao) {
....
}
this.result = String(sum)
return
}
if (data === 'AC') {
this.num1 = this.num2 = this.fuhao = this.result = ''
return
}
// if (data==='+' || data==='-') {
if (['+','-','x','÷'].includes(data)) {
this.fuhao = data
return
}
if (this.fuhao) {
this.num2 += data
} else {
this.num1 += data
}
1列5行
Column w100% h100% bg#000 padding30
结果展示 Row w100% h40%
Text 233 w100% textAigin居中 fontSize 80 color #fff
第一行 Row w100% h15%
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
...
第四行 Row w100% h15%
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
Text 数字 w75 h75 bg#333 font-size30 color #fff 圆角75 textAigin居中
模型 total = 0 视图渲染 后续得下次上课讲解
1、完成了 每个数字点击保存到 num1
2、完成了 每个符号点击保存
3、完成的AC清空
4、缺 每个数字点击 判断 符号选没选 没选-保存到num1中 选了-保存到num2
5、 计算结果
@Extend(Text) function textStyle(active: boolean) {
.fontSize(30).fontColor('#fff').textAlign(TextAlign.Center)
.width(75).height(75)
.backgroundColor(active ? '#daaa60': '#333')
.borderRadius(75)
}
@Entry
@Component
struct Index {
// 1 布局
// 2 声明状态 4个 =》 视图去用一下
// 3 绑定事件 交给一个函数处理 onResult
// 4 先处理数字、处理符号、处理第二个数字、AC、=
@State num1:string = ''
@State fuhao:string = ''
@State num2:string = ''
@State result:string = ''
onResult(data:string) {
if (data === '=') {
let sum:number = 0
switch (this.fuhao) {
case '+':
sum = Number(this.num1) + Number(this.num2)
break;
case '-':
sum = Number(this.num1) - Number(this.num2)
break;
case 'x':
sum = Number(this.num1) * Number(this.num2)
break;
case '÷':
sum = Number(this.num1) / Number(this.num2)
break;
default:
break;
}
this.result = String(sum)
return
}
if (data === 'AC') {
this.num1 = this.num2 = this.fuhao = this.result = ''
return
}
// if (data==='+' || data==='-') {
if (['+','-','x','÷'].includes(data)) {
this.fuhao = data
return
}
if (this.fuhao) {
this.num2 += data
} else {
this.num1 += data
}
}
// button: string|number[] = [7,8,9,'+']
// button: Array<string|number> = [7,8,9,'+']
// button: Array<string|number> = [4,5,6,'-']
// button: Array<string|number> = [1,2,3,'x']
// button: Array<string|number> = [0,'AC','=','÷']
// button: Array<原始类型>
// button: Array<引用类型>
button: Array<Array<string|number>> = [
[7,8,9,'+'],
[4,5,6,'-'],
[1,2,3,'x'],
[0,'AC','=','÷']
]
build() {
Column() {
// 结果布局
Column() {
Text(`${this.num1}${this.fuhao}${this.num2}`).fontSize(80).fontColor(Color.White).width('100%').textAlign(TextAlign.End)
Text(this.result).fontSize(80).fontColor(Color.White).width('100%').textAlign(TextAlign.End)
}.width('100%').height('40%')
// 结果布局 end
// 计算器页面
// Row() {
// Text('7').textStyle()
// Text('8').textStyle()
// Text('9').textStyle()
// Text('+').textStyle()
// }.width('100%').height('15%')
// 行
ForEach(this.button, (item: Array<string|number>) => {
Row() {
ForEach(item, (item2: string|number, i2:number) => {
// Text(String(item2)).textStyle()
Text(item2.toString())
.textStyle(i2===3)
.onClick(() => this.onResult(item2.toString()))
.stateStyles({
pressed: {
.backgroundColor('#ccc')
}
})
})
}.width('100%').height('15%')
})
// 计算器页面 end
}
.width('100%')
.height('100%')
.backgroundColor(Color.Black)
.padding(30)
}
}
待办列表
# 待办思路
一、布局
Column
Text待办标题
Row
TextInput
Button
Row 待办列表
Checkbox
Text
二、声明状态、待办列表循环展示(记得加类型)
@State todos: TodoType[] = [
new TodoType('早起晨练', true),
new TodoType('准备早餐', false),
new TodoType('阅读名著', true),
new TodoType('学习ArkTs', false),
new TodoType('看剧轻松', false),
]
三、追加数据
- 3.1 声明content状态
- 3.2 给TextInput绑定值改变事件 保存content中
- 3.3 给Button绑定点击事件 push数据
四、给Checkbox绑定改变事件
Checkbox().select(item.finished).width(30).onChange((value:boolean) => {
// item.finished = value
// this.todos[i].finished = value 修改一维没有响应式效果
// console.log(item.title, item.finished)
this.todos[i] = new TodoType(item.title, value)
})
class Todo {
title: string
finished: boolean
constructor(title:string, finished: boolean) {
this.title = title
this.finished = finished
}
}
@Entry
@Component
struct Demo7 {
title:string = ''
@State todos: Todo[] = [
new Todo('早起晨练', true),
new Todo('准备早餐', false),
new Todo('阅读名著', true),
new Todo('学习ArkTs', false),
new Todo('看剧轻松', false),
]
onAddTodo = (title: string) => {
this.todos.unshift(new Todo(title, false))
}
build() {
Column() {
// 标题
Row() {
Text('待办').fontSize(40).fontWeight('bold')
}
.width('100%')
.margin({top:20,bottom:20})
// 输入
Row() {
TextInput({placeholder:'请输入内容'})
.width('75%').height(50).backgroundColor('#fff')
.fontSize(20)
.placeholderFont({size:20})
.onChange((value: string) => {
// console.log(value)
this.title = value
})
Button('添加', {type: ButtonType.Normal}).width('20%').margin({left:'5%'})
.onClick(() => {
this.onAddTodo(this.title)
})
}
.width('100%')
.margin({bottom:20})
// 内容
ForEach(
this.todos,
(item:Todo, index:number) => {
Row() {
Checkbox().select(item.finished).onChange((value:boolean) => {
// console.log(String(value))
// this.todos[index].finished = value
// 修改n层 不会有响应式效果
this.todos[index] = new Todo(item.title, value)
})
.width(28)
Text(item.title)
.fontSize(28)
.padding({left:10})
.fontColor(item.finished ? '#B1B2B1' : '#000')
.decoration({
type: item.finished ? TextDecorationType.LineThrough : TextDecorationType.None,
})
}
.width('100%')
.backgroundColor('#fff')
.padding(15)
.margin({bottom:20})
.borderRadius(20)
}
)
}
.width('100%')
.height('100%')
.backgroundColor('#eff2f4')
.padding(15)
}
}
百度日历 选些
a 日历
https://appgallery.huawei.com/app/C100576593
https://appgallery.huawei.com/app/C104573519
b 布局
class Day {
year:number
month:number
day:number
type: 'prev' | '' | "current" | 'next'
constructor(year:number,month:number, day:number, type:'prev' | '' | "current" | 'next') {
this.year = year
this.month = month
this.day = day
this.type = type
}
}
@Entry
@Component
struct Index {
weekName:string[] = ['一', '二', '三', '四', '五', '六', '日']
@State data:Day[][] = [
[
new Day(2024, 1, 29, 'prev'),
new Day(2024, 1, 30, 'prev'),
new Day(2024, 1, 31, 'prev'),
new Day(2024, 2, 1, 'current'),
new Day(2024, 2, 2, ''),
new Day(2024, 2, 3, ''),
new Day(2024, 2, 4, ''),
],
[
new Day(2024, 2, 5, ''),
new Day(2024, 2, 6, ''),
new Day(2024, 2, 7, ''),
new Day(2024, 2, 8, ''),
new Day(2024, 2, 9, ''),
new Day(2024, 2, 10, ''),
new Day(2024, 2, 11, ''),
],
]
build() {
Column() {
Row() {
ForEach(this.weekName, (item:string) => {
Text(item).width('15%').fontSize(30).fontColor('#fff').textAlign(TextAlign.Center)
})
}
.margin({bottom:20})
ForEach(this.data, (temp: Day[]) => {
Row() {
ForEach(temp, (item:Day) => {
Text(String(item.day)).width('15%').fontSize(30).fontColor('#fff').textAlign(TextAlign.Center)
})
}
.margin({bottom:20})
})
}
.width('100%')
.height('100%')
.backgroundColor('#000')
.padding(30)
}
}
c 语法
思想1
1、html 可以写网页的基本结构 css 可以美化网页 =》 淘宝、京东这样的网页 只不过都是静态的 没有交互交互 返回顶部、轮播图、登录表单验证之类的
2、js 加特性 加用户和网页之间的交互 例如计算器、登录表单验证等等
想要加特效就得把数据存起来
let ipt = document.qs('input')
3、ts 加类型限制 string、number 写的代码可读性、可扩展性更强 相对而言参考java
3、ArkTS 基于 ts 进一步升级
思想2:可以存放哪些数据
原始类型:7小类 null/undefined bool/string/number Symbol/bigint
let data1 = 111
let data2 = 222
let data3 = true
let data4 = '我爱中国'
对象类型:4小类
- 标准普通对象 {}
- 标准特殊对象 [] 日期、数学
- 非标准特殊对象
- 可调用可执行
let arr = [111,22,3333]
arr[索引]
let obj = {
属性名: 数据,
属性名: 数据,
属性名: 数据,
year: 2024
}
obj.属性名
上面这个相对而言都是存的普通数据,
js针对于特殊场景也有特殊对象
Math.ceil()
Math.floor() ...
let obj = new Date()
let date = new Date() 日期对象 特殊的 通过它能获取当前的时间
date.getFullYear() 获取当前的年 自动获取
date.getMonth() 获取当前的月 0~11 实际生活1-12 所以用的时候得+1
data 数据
date 日期 简写d
创建日期对象: let date = new Date()
获取当前年份: date.getFullYear()
获取当前月份: date.getMonth() 返回0~11 实际使用+1 生活中 1~12
获取当前几号/日期: date.getDate() 例如今天27号
获取当前星期几: date.getDay() 留心返回的是0~6 0代表星期日
例如微信朋友圈 刚刚、几分钟、几小时;包括美团外卖倒计时等等
有印象些项目会用记性 参考之前生命倒计时 new Date('2024-02-27 12:00:00')
获取本月多少天: let currentLastHao = new Date(当前年2024, 当前月2, 数字).getDate() (LastHao 我想表达2月最后一天 29
留心:数字0 代表本月最后一天 例如2月就是29 数字-1 代表倒数第二天 也就是28 数字-2代表倒数第三天 也就是27
获取本月1号星期几:new Date(当前年, 当前月-1, 1).getDay() 单独记忆 不用管参数啥意思
d 本月
1、布局 页面增加今天按钮绑定点击事件
2、事件处理函数中
-
2.1 获取本月多少天
-
2.2 通过for循环 生成 1~29号
-
2.3 保存数据同步页面展示
// # 本月
// 1、获取本月最后一天 也就是一共多少天 例如2月29天
// let currentLastHao = new Date(2024, 2, 0).getDate() // 当前月最后一天是多少号
// 留心:new Date里面写月份时候 切记2月要写成1 因为getMonth()返回的是0~11
let currentLastHao = new Date(this.currentYear, this.currentMonth+1, 0).getDate()
console.log(String('当前月有多少天:' + currentLastHao)) // console.log不能打印数值类型 需要转字符串
// 2、循环生成1-29天
// 原生数组循环: [数据,...,数据].forEach((item, i) => { console.log(item,i) }) // item是数组中的每个值 i是对应的索引
// 鸿蒙数组循环 ForEach(数据, (item, i) => {)
// 数字for循环 for (变量; 判断; 运算) {}
let temp: Day[] = [] // 用来存放当前月所有日期 先临时存放下 最后按照规律放到data中
for (let hao=1; hao<=currentLastHao; hao++) {
// console.log(hao)
// console.log(String(hao))
// console.log(hao.toString())
// temp.push(数据) 给数组中追加一条数据 这个语法我估摸着也有小伙伴忘了 得补一补
// temp.push(new Day(2024, 2, 2, ' '))
temp.push(new Day(this.currentYear, this.currentMonth, hao, ''))
}
// 打印temp是否存了29天 日期对象 因为存了 咱们才可以页面/视图去展示, 为什么不立马存到data
// 因为data不适合立马存,他需要 7天一存 7天一存 因为 效果图一行7天
// 因此用temp临时存放一下
// console.log(temp) // 留心有坑 console.log语法只能打印字符串 不能打印对象类型
// 解决:通过内置API JSON.stringify(数据) 可以把数组转字符串打印查看 工作常用
// console.log(JSON.stringify(temp))
// 3、保存到模型中 =》 目的同步页面展示
// 思考:哪一个模型?
// 回答:data = [
// 第一层数据 行 1行 [列1, 列2, ...]
// 第一层数据 行 2行 [列1, 列2, ...]
// 第一层数据 行 3行 [列1, 列2, ...]
// ]
// this.data = temp 不对 因为data是多层级的数组 temp是一层
// this.data = [
// temp, 但是每个temp里面只能有7条数据 而我们有29条
// temp,
// ]
// 家人们脑瓜子疼了 如何把29条分配进去
// 1 搞一个tempSmall变量 默认空数组
let tempSmall = []
// 2 循环temp 每7个存到tempSmall变量中 筹齐7个 咱们就是push到data里面 并清空 继续筹齐后见面的7个 以此类推
for (let i=0; i<temp.length; i++) {
if (tempSmall.length%7===0) {
this.data.push(tempSmall)
tempSmall = []
}
// temp中每个数据 temp[i] 0 1 2 3
tempSmall.push(temp[i])
}
// 留心:4*7=28 29这个数据在循环中 没有清楚 仅仅保存了 然后退出循环 但是这条数据还得要
if (tempSmall.length) this.data.push(tempSmall)
// ...
e 上月剩余
let temp: Day[] = [] // 用来存放当前月所有日期 先临时存放下 最后按照规律放到data中
// # 上月:也就是给temp里面追加数据 最后保存的时候会每7个计算
// 1-每月1号星期几 1月1号星期1一个不展示、2月1号星期4-展示3、3月1号星期5-展示4
// 获取本月1号星期几:new Date(当前年, 当前月-1, 1).getDay()
let weekNameNum = new Date(this.currentYear, this.currentMonth, 1).getDay() // 返回0-6
// console.log('1月1号,星期2')
// console.log('1月1号,星期weekNameNum')
// console.log('1月1号,星期'+weekNameNum) // 字符串+数字 = 字符串
// console.log('1月1号,星期'+weekNameNum) // es6语法升级了 `内容 ${变量} `
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// 2-从数字几开始展示 2月31向前展示 3月29向前展示
// 获取本月最后一天
// let currentLastHao = new Date(this.currentYear, this.currentMonth+1, 0).getDate()
// 获取上个月最后一天
let prevLastHao = new Date(this.currentYear, this.currentMonth, 0).getDate()
// console.log(`上月最后一天:${prevLastHao}号`) // 1月31天
// 计算展示上月数据 上月展示几个取决于星期几
// 星期5 1-4
// 星期4 1-3
// 2月为例 星期4 1-3 为啥-1星期四前面只要展示3个数据
for (let num=weekNameNum-1; num>0; num--) {
// num prevLastHao
// 3 31 -num3+1=29
// 2 31 -num2+1=30
// 1 31 -num1+1=31
// temp.push(new Day(this.currentYear, this.currentMonth, ???, 'prev'))
temp.push(new Day(this.currentYear, this.currentMonth, prevLastHao-num+1, 'prev'))
}
f 下月剩余
// 下月:42-上月天数和本月天数 剩余就是下月 从1开始递增
let nextNum = 42-temp.length
for (let i=1; i<=nextNum; i++) {
temp.push( new Day(this.currentYear, this.currentMonth+1, i, 'next'))
}
g 上下月按钮
Button('上月')
.onClick(() => {
this.data = []
this.currentMonth--
this.getData()
})
Button('今天')
.onClick(() => {
this.data = []
this.currentMonth = this.currentDate.getMonth()
this.getData()
})
Button('下月')
.onClick(() => {
this.data = []
this.currentMonth++
this.getData()
})
h 完整代码
class Day {
y:number
m:number
d:number
type:'prev'|'current'|'next'|''
// constructor(y:number,m:number,d:number,type:string) {
// 联合类型 & 字符面类型 也就是字符串范围非常广 这个限制了只能4种情况 更严谨
// pre是上月日期
// current 本月当前日期 27
// next下月日期
constructor(y:number,m:number,d:number,type:'prev'|'current'|'next'|'') {
this.y = y
this.m = m
this.d = d
this.type = type
}
}
@Entry
@Component
struct Index {
currentDate: Date = new Date()
currentYear: number = this.currentDate.getFullYear()
@State currentMonth: number = this.currentDate.getMonth() // 返回的是0~11 生活中得+1 也就是1-12月
currentHao: number = this.currentDate.getDate()
@State weekName:string[] = ['一', '二', '三', '四', '五', '六', '日']
@State data:Day[][] = [ // 切记多为数组,也就是数组里面不是直接的书,而是又是数组
// 获取第一行 this.data[0]
// [
// new Day(2024, 1, 29, 'prev'),
// new Day(2024, 1, 30, 'prev'),
// new Day(2024, 1, 31, 'prev'),
// new Day(2024, 2, 1, 'current'),
// new Day(2024, 2, 2, ''),
// new Day(2024, 2, 3, ''),
// new Day(2024, 2, 4, ''),
// ],
// 获取第二行 this.data[1]
// [
// new Day(2024, 2, 5, ''),
// new Day(2024, 2, 6, ''),
// new Day(2024, 2, 7, ''),
// new Day(2024, 2, 8, ''),
// new Day(2024, 2, 9, ''),
// new Day(2024, 2, 10, ''),
// new Day(2024, 2, 11, ''),
// ],
// 获取第三行 this.data[2]
// [
// new Day(2024, 2, 5, ''),
// new Day(2024, 2, 6, ''),
// new Day(2024, 2, 7, ''),
// // new Day(2024, 2, 8, ''),
// // new Day(2024, 2, 9, ''),
// // new Day(2024, 2, 10, ''),
// // new Day(2024, 2, 11, ''),
// ],
]
getData = () => {
let temp: Day[] = [] // 用来存放当前月所有日期 先临时存放下 最后按照规律放到data中
// # 上月:也就是给temp里面追加数据 最后保存的时候会每7个计算
// 1-每月1号星期几 1月1号星期1一个不展示、2月1号星期4-展示3、3月1号星期5-展示4
// 获取本月1号星期几:new Date(当前年, 当前月-1, 1).getDay()
let weekNameNum = new Date(this.currentYear, this.currentMonth, 1).getDay() // 返回0-6
// console.log('1月1号,星期2')
// console.log('1月1号,星期weekNameNum')
// console.log('1月1号,星期'+weekNameNum) // 字符串+数字 = 字符串
// console.log('1月1号,星期'+weekNameNum) // es6语法升级了 `内容 ${变量} `
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// console.log(`${this.currentMonth+1}月1号,星期${weekNameNum}`)
// 2-从数字几开始展示 2月31向前展示 3月29向前展示
// 获取本月最后一天
// let currentLastHao = new Date(this.currentYear, this.currentMonth+1, 0).getDate()
// 获取上个月最后一天
let prevLastHao = new Date(this.currentYear, this.currentMonth, 0).getDate()
// console.log(`上月最后一天:${prevLastHao}号`) // 1月31天
// 计算展示上月数据 上月展示几个取决于星期几
// 星期5 1-4
// 星期4 1-3
// 2月为例 星期4 1-3 为啥-1星期四前面只要展示3个数据
for (let num=weekNameNum-1; num>0; num--) {
// num prevLastHao
// 3 31 -num3+1=29
// 2 31 -num2+1=30
// 1 31 -num1+1=31
// temp.push(new Day(this.currentYear, this.currentMonth, ???, 'prev'))
temp.push(new Day(this.currentYear, this.currentMonth, prevLastHao-num+1, 'prev'))
}
// # 本月
// 1、获取本月最后一天 也就是一共多少天 例如2月29天
// let currentLastHao = new Date(2024, 2, 0).getDate() // 当前月最后一天是多少号
// 留心:new Date里面写月份时候 切记2月要写成1 因为getMonth()返回的是0~11
let currentLastHao = new Date(this.currentYear, this.currentMonth+1, 0).getDate()
console.log(String('当前月有多少天:' + currentLastHao)) // console.log不能打印数值类型 需要转字符串
// 2、循环生成1-29天
// 原生数组循环: [数据,...,数据].forEach((item, i) => { console.log(item,i) }) // item是数组中的每个值 i是对应的索引
// 鸿蒙数组循环 ForEach(数据, (item, i) => {)
// 数字for循环 for (变量; 判断; 运算) {}
// let temp: Day[] = [] // 用来存放当前月所有日期 先临时存放下 最后按照规律放到data中
for (let hao=1; hao<=currentLastHao; hao++) {
// console.log(hao)
// console.log(String(hao))
// console.log(hao.toString())
// temp.push(数据) 给数组中追加一条数据 这个语法我估摸着也有小伙伴忘了 得补一补
// temp.push(new Day(2024, 2, 2, ' '))
// temp.push(new Day(this.currentYear, this.currentMonth+1, hao, ''))
if (hao === this.currentHao) {
temp.push(new Day(this.currentYear, this.currentMonth+1, hao, 'current'))
} else {
temp.push(new Day(this.currentYear, this.currentMonth+1, hao, ''))
}
}
// 下月:42-上月天数和本月天数 剩余就是下月 从1开始递增
let nextNum = 42-temp.length
for (let num=1; num<=nextNum; num++) {
temp.push(new Day(this.currentYear, this.currentMonth+1+1, num, 'next'))
}
// 打印temp是否存了29天 日期对象 因为存了 咱们才可以页面/视图去展示, 为什么不立马存到data
// 因为data不适合立马存,他需要 7天一存 7天一存 因为 效果图一行7天
// 因此用temp临时存放一下
// console.log(temp) // 留心有坑 console.log语法只能打印字符串 不能打印对象类型
// 解决:通过内置API JSON.stringify(数据) 可以把数组转字符串打印查看 工作常用
// console.log(JSON.stringify(temp))
// 3、保存到模型中 =》 目的同步页面展示
// 思考:哪一个模型?
// 回答:data = [
// 第一层数据 行 1行 [列1, 列2, ...]
// 第一层数据 行 2行 [列1, 列2, ...]
// 第一层数据 行 3行 [列1, 列2, ...]
// ]
// this.data = temp 不对 因为data是多层级的数组 temp是一层
// this.data = [
// temp, 但是每个temp里面只能有7条数据 而我们有29条
// temp,
// ]
// 家人们脑瓜子疼了 如何把29条分配进去
// 1 搞一个tempSmall变量 默认空数组
let tempSmall = []
// 2 循环temp 每7个存到tempSmall变量中 筹齐7个 咱们就是push到data里面 并清空 继续筹齐后见面的7个 以此类推
for (let i=0; i<temp.length; i++) {
if (tempSmall.length%7===0) {
this.data.push(tempSmall)
tempSmall = []
}
// temp中每个数据 temp[i] 0 1 2 3
tempSmall.push(temp[i])
}
// 留心:4*7=28 29这个数据在循环中 没有清楚 仅仅保存了 然后退出循环 但是这条数据还得要
if (tempSmall.length) this.data.push(tempSmall)
// ...
}
build() {
Column() {
// 布局:一行一行写
// 难点:js获取上个月有几号,当前页有几号,下个月几号
// 标题1
Text('百度日历 📅').width('100%').fontColor('#fff').fontSize(50).textAlign(TextAlign.Center).margin({top:20,bottom:20})
// 标题2
// Text('2024年2月').width('100%').fontColor('#fff').fontSize(30).textAlign(TextAlign.Center).margin({top:20,bottom:20})
Text(`2024年${this.currentMonth+1}月`).width('100%').fontColor('#fff').fontSize(30).textAlign(TextAlign.Center).margin({top:20,bottom:20})
// 标题3
// 一、二、三、四、五、六、日
Row() {
ForEach(
this.weekName,
(item:string) => {
Text(item).width('15%').fontSize(30).fontColor('#fff').textAlign(TextAlign.Center)
}
)
}
.width('100%')
.margin({bottom:20})
// 29、30、31、1、2、3、4
// 5、6、7、8、9、10、11
ForEach(
this.data,
(rowItem: Day[]) => {
// 行
Row() {
// 列 根据rowItem里面对象 一个对象一列
ForEach(
rowItem,
(colItem:Day) => {
if (colItem.type === 'current') {
Text(String(colItem.d))
.width('15%')
// .backgroundColor(colItem.type==='prev' || colItem.type ==='next' ? '#ccc' : '#000')
.backgroundColor('red')
.fontSize(30)
.fontColor('#fff')
.textAlign(TextAlign.Center)
} else {
Text(String(colItem.d))
.width('15%')
// .backgroundColor(colItem.type==='prev' || colItem.type ==='next' ? '#ccc' : '#000')
.backgroundColor(['prev','next'].includes(colItem.type) ? '#ccc' : '#000')
.fontSize(30)
.fontColor('#fff')
.textAlign(TextAlign.Center)
}
}
)
}
.width('100%')
.margin({bottom:20})
}
)
// 按钮组
Row() {
Button('上月')
.onClick(() => {
this.data = []
this.currentMonth--
this.getData()
})
Button('今天')
.onClick(() => {
this.data = []
this.currentMonth = this.currentDate.getMonth()
this.getData()
})
Button('下月')
.onClick(() => {
this.data = []
this.currentMonth++
this.getData()
})
}
// ...
}
.width('100%')
.height('100%')
.padding(30)
.backgroundColor('#000')
}
}
欢迎加入课程班级,考取鸿蒙认证: