1.1 字符串
// 变量的存储和修改(string number boolean)
// 1. 变量存储
// 1.1 字符串 string 类型
// 注意点1:字符串需要用引号引起来(单引双引号)'字符串' "字符串"
// 注意点2:存储的时候,后面的存的内容,需要和前面的类型对应
let title: string = '巨无霸汉堡'
console.log('字符串title', title)// 1.2 数字 number 类型
let age: number = 18
console.log('年纪age', age)// 1.3 布尔 boolean 类型(true真,false假)
let isLogin: boolean = false
console.log('是否登录成功', isLogin)// 2. 变量的修改
age = 40
console.log('年纪age', age)// 常量
const PI: number = 3.14
const companyName: string = '华为'
console.log('公司名:', companyName)
console.log('PI:', PI)// 字符串拼接 + 拼串
let name: string = '吕布'
let age: number = 18
console.log('简介信息:', '姓名' + name)
console.log('简介信息:', '年纪' + age)// 注意点: + 两边只要有字符串, 就是拼串的作用 (如果两边都是数字, 就是计算求和的作用)
let num1: number = 100
let num2: number = 200
console.log('总数', num1 + num2)---------------------------------------------
// 模板字符串 `` (支持变量, 更利于字符串拼接) 普通字符串 '' ""
// let str: string = `hello world`
//let name: string = '成小龙'let age: number = 18let hobby: string = '打拳'console.log('简介信息', `姓名: ${name}, 年纪: ${age}岁, 爱好: ${hobby}`)
1.2 数组
// 学生数组
// 语法:
// let 数组名: 类型[] = [数据1, 数据2, 数据3, ... ]// 1.数组中存储的每个数据,都有自己的编号,编号从0开始(索引)
let names: string[] = ['刘亦菲', '杨颖', '杨幂', '刘诗诗', '伍佰']
console.log('数组names', names)// 2.利用有序的编号(索引) 取数组的数据
// 取数据:数组名[索引]
console.log('取到了', names[3])// 3. 数组修改(通过下标)
names[2] = '赵云'
console.log('修改数组', names)// 4.添加
// 1. 往开头新增 unshift(新增的值) 返回操作后的数组的长度songs.unshift('彩虹')console.log('返回数组长度', songs.unshift('七里香'))
console.log('数组songs', songs)// 5. 往结尾新增 push(新增的值) 返回操作后的数组的长度songs.push('光辉岁月', '海阔天空')
console.log('数组', songs)// 6.删除
// 1. 从开头删 shiftconsole.log('返回删除的项', songs.shift())console.log('返回删除的项', songs.shift())console.log('数组', songs)// 7. 从结尾删 popsongs.pop()songs.pop()songs.pop()
console.log('数组', songs)// 开头(S): unshift(开头增) shift(开头删)
// 结尾(P): push(结尾增) pop(结尾删)// 8.定义一个数组
let songs: string[] = ['告白气球', '洋葱', '吻别', '双节棍', '曹操']
// splice 在任意位置进行删除或新增内容
// 数组名.splice(操作的起始位置, 删除几个, 新增的项1, 新增的项2, ...)// 8.1. 删除(任意位置)
// songs.splice(2, 2)
// console.log('数组songs', songs)// 8.2. 新增(任意位置)
// songs.splice(1, 0, '彩虹') // 新增// 8.3. 替换(删了一项, 又加了一项)
// songs.splice(1, 1, '彩虹')
// console.log('数组songs', songs)-----------------------------剩余参数和展开运算符---------------------------
// ...数组名 => 可以收集剩余的参数
function sum (n1: number, n2: number, ...argsArr: number[]) {let total: number = n1 + n2// 遍历剩余参数, 如果有剩余的参数, 就继续累加for (let temp of argsArr) {total += temp}console.log('结果', total)return total
}
sum(1, 2)
sum(1, 2, 3, 4)
sum(1, 2, 3, 4, 5, 6)// ... 展开运算符, 用于数组的平铺合并
let arr1: number[] = [1,2,3]
let arr2: number[] = [4,5,6]
let newArr: number[] = [...arr1, ...arr2]
console.log('最终的数组', newArr)
1.3 函数
// 1. 定义函数 (只是定义了函数,但是没有使用,不会执行内部的代码段)
function star() {console.log('五角星', '☆')console.log('五角星', '☆☆')console.log('五角星', '☆☆☆')console.log('五角星', '☆☆☆☆')console.log('五角星', '☆☆☆☆☆')
}
// 2. 调用函数(使用函数)
// 函数名()
star()//3.带返回值对函数
function buy(price: number, num: number) {console.log('传入的数据', price, num)// 1. 处理数据let result: number = price * num// 2. 返回结果return result
}//4.函数调用
let apple: number = buy(2, 3)
console.log('苹果', apple)let banana: number = buy(4, 4)
console.log('香蕉', banana)
// 注意点:形参和实参的数量要统一,一一对应
1.4 箭头函数
//1.构建函数
let buy = (price: number, weight: number) => {// 1. 计算数据let result: number = price * weight// 2. 返回计算的结果return result
}
//2.调用函数
let apple: number = buy(2, 3)
console.log('苹果', apple)
1.5 定义接口-对象
// 1. 定义接口
interface Person {name: stringage: numberweight: number
}// 2. 基于接口,定义对象
let ym: Person = {name: '大幂幂',age: 18,weight: 90
}// 3. 获取对象属性值 对象名.属性名
console.log('体重:', ym.weight)
1.6 对象-方法的使用
// 1. 定义接口
interface Person {name: stringage: numberweight: number// ① 定义方法的类型sing: (song: string) => voiddance: () => void
}// 2. 基于接口,定义对象
let ym: Person = {name: '大幂幂',age: 18,weight: 90,// ② 定义方法sing: (song: string) => {console.log('杨幂说', '我来唱首歌', song)},dance: () => {console.log('杨幂说', '我来跳个舞')}
}// ③ 调用对象里面的方法 (重要!!)
ym.sing('爱的供养')
ym.dance()
1.7 联合类型
// 联合类型还可以将变量值,约定在一组数据范围内进行选择
// 性别:男 女 保密
let gender: 'man' | 'woman' | 'secret' = 'secret'
1.8 枚举
// 1. 定义枚举 (定义常量列表)
enum ThemeColor {Red = '#ff0f29',Orange = '#ff7100',Green = '#30b30e'
}// 2. 给变量设定枚举类型
let color: ThemeColor = ThemeColor.Orange
console.log('color', color)
2.0控件-按钮
2.1.控件-文本框
Text(this.message).fontSize(40) // 设置文本的文字大小.fontWeight(FontWeight.Bolder) // 设置文本的粗细.fontColor(Color.Red) // 设置文本的颜色-------------------------------------------------------------------------
//设置边框Text('待完善').fontColor(Color.Red).padding(5).border({width: 1, // 宽度(必须)color: Color.Red, // 颜色style: BorderStyle.Dashed // 样式(实线、虚线、点线)}).margin({ bottom: 20 })
-------------------------------------------------------------------------
//设置单边框Text('单边框').padding(5)// 单边框,可以通过 left right bottom top 配置四个方向边框.border({width: { left: 1, right: 2 },color: { left: Color.Red, right: Color.Green },style: {left: BorderStyle.Dashed,right: BorderStyle.Dotted}})
---------------------------------------------------------------------// 添加圆角:// 1. .borderRadius(数值) 四个角圆角相同// 2. .borderRadius({ 方位词: 值 }) 单独给某个角设置圆角Text('添加圆角').width(100).height(60).backgroundColor(Color.Orange)// .borderRadius(15) // 通过不同数值,可以设置不同大小的圆角// .borderRadius({// topLeft: 10,// topRight: 20,// bottomRight: 30,// bottomLeft: 40// }).borderRadius({topLeft: 20,bottomRight: 20})
---------------------------------------------------------------------
//添加背景图片
Text('我是内容文本').fontColor(Color.White).width(300).height(200).backgroundColor(Color.Pink)// backgroundImage(加载的背景图片, 是否平铺ImageRepeat枚举).backgroundImage($r('app.media.flower'), ImageRepeat.XY )
--------------------------------------------------------------------
//设置背景图片的位置// backgroundImagePosition// 1. 传入对象, 设置位置坐标,背景图片的左顶点// { x: 坐标值, y: 坐标值 }// 注意:坐标值的单位,和宽高的默认单位不同的,显示出来大小会不同//// 2. Alignment 枚举,设置一些特殊的位置(中央、左顶点...)// Center TopStart左顶点 TopEnd右顶点 BottomEnd右下...Column() {Text().width(300).height(200).backgroundColor(Color.Pink).backgroundImage($r('app.media.flower')).backgroundImagePosition({x: 400,y: 300}).backgroundImagePosition(Alignment.BottomEnd)}.padding(20)}
------------------------------------------------------
//设置图片位置vp转pxText().width('300vp').height('200vp').backgroundColor(Color.Pink).backgroundImage($r('app.media.flower')).backgroundImagePosition({x: vp2px(150),y: vp2px(100)})
---------------------------------------------------------
//设置背景图是否缩放Text().width(330).height(200).backgroundColor(Color.Pink).backgroundImage($r('app.media.jd_bg')).backgroundImagePosition(Alignment.Center).backgroundImageSize(ImageSize.Cover)// 1. 直接写 宽高尺寸 对象// .backgroundImageSize({// width: 150,// // height: 100// })// 2. 设置 背景尺寸 的枚举 ImageSize// (1) Contain: 等比例缩放,展示整张图片,可能会留白// (2) Cover: 等比例缩放,让图片铺满整个容器,不会留白,但是有可能会有部分内容显示不全
2.2 控件-行和列
//列 Column() {}.width('100%').height('100%').backgroundColor('#ffe8eeee')//行Row() {}.justifyContent(FlexAlign.SpaceEvenly).width('90%').height(30).onClick(() => {router.pushUrl({url: "pages/LanguageChoice"})})
-------------------------------------------------------------------// 控制组件间的距离,可以给 Column 设置 { space: 间隙大小 }Column({ space: 15 }) {}---------------------------------------------------------------
// 设置排布主方向的对齐方式(主轴)// 1. Start (排布主方向)主轴起始位置对齐// 2. Center 主轴居中对齐// 3. End 主轴结束位置对齐// 4. SpaceBetween 贴边显示,中间的元素均匀分布间隙// 5. SpaceAround 间隙环绕 0.5 1 1 1 0.5 的间隙分布,靠边只有一半的间隙// 6. SpaceEvenly 间隙均匀环绕,靠边也是完整的一份间隙// justifyContent(枚举FlexAlign) ctrl+p cmd+p// .justifyContent(FlexAlign.Center)// .justifyContent(FlexAlign.SpaceBetween)// .justifyContent(FlexAlign.SpaceAround).justifyContent(FlexAlign.SpaceEvenly)
2.3控件-输入框
TextInput({placeholder: '请输入密码'}).type(InputType.Password)
2.4控件控制-权重
// // layoutWeight 自适应伸缩: 按照[份数权重],分配[剩余空间]Text('左侧').layoutWeight(1).height(40).backgroundColor(Color.Pink)Text('右侧固定').width(80).height(40).backgroundColor(Color.Orange)
2.5控件-图片显示
Image($r('app.media.ic_like')).width(12).fillColor('#999')
----------------------------------------------Image($r('app.media.position_earphone')).width(20).backgroundColor('#55b7f4').borderRadius(10).padding(3).fillColor(Color.White).margin({ left: 6, right: 6 })
2.6控件-角标
Badge({count: 1,position: BadgePosition.RightTop,style: {fontSize: 14,badgeSize: 20,badgeColor: '#fa2a2d'}}) {Image($r('app.media.bg_01')).width(100)}
2.7 控件-绝对定位
// position绝对定位:可以控制组件位置,可以实现层叠效果// 语法:// .position({// x: 50,// y: 50// })// 特点:// 1. 相对于父组件左顶点进行偏移(调整位置)// 2. 原本的位置不占了,且可以任意调整位置,不影响其他元素// 后面的组件明显层次更高,会盖住前面的组件// 需求:不动结构的情况下,调整组件的层级 .zIndex(数字)Column() {Text('大儿子').width(80).height(80).backgroundColor(Color.Green).zIndex(3)Text('二儿子定位').width(80).height(80).backgroundColor(Color.Yellow).position({x: 50,y: 50}).zIndex(4)Text('三儿子').width(80).height(80).backgroundColor(Color.Orange).zIndex(2)}.width(300).height(300).backgroundColor(Color.Pink)
2.8 控件-AlertDialog
AlertDialog.show({message: '最小值为1, 不能再减了'})
2.9 控件设置-设置字符串,颜色,图片等
//设置文字
$r('app.string.EntryAbility_label')
//设置颜色
$r('app.color.main_text')
2.10 控件-Swiper
// Swiper 轮播组件的基本使用// 1. Swiper 包内容// 2. Swiper 设尺寸Swiper() {Image($r('app.media.ic_swiper_xmyp01'))Image($r('app.media.ic_swiper_xmyp02'))Image($r('app.media.ic_swiper_xmyp03'))Image($r('app.media.ic_swiper_xmyp04'))}.width('100%').height(150).loop(true) // 开启循环.autoPlay(true) // 自动播放.interval(5000) // 自动播放间隔.vertical(true) // 纵向---------------------------定制小圆点--------------------------------// Swiper 轮播组件的基本使用// 1. Swiper 包内容// 2. Swiper 设尺寸Swiper() {Text('1').backgroundColor(Color.Orange)Text('2').backgroundColor(Color.Yellow)Text('3').backgroundColor(Color.Brown)}.width('100%').height(200)// 常用属性.loop(true) // 开启循环.autoPlay(true) // 自动播放.interval(5000) // 自动播放间隔.vertical(false) // 横向/纵向// 定制小圆点// .indicator(false).indicator(Indicator.dot().itemWidth(20).itemHeight(20).color(Color.Black).selectedItemWidth(25).selectedItemHeight(25).selectedColor(Color.White))---------------------轮播案例------------------------// 1. Swiper轮播容器 (填入内容)Swiper() {Image($r('app.media.1')).objectFit(ImageFit.Cover)Image($r('app.media.2')).objectFit(ImageFit.Cover)Image($r('app.media.3')).objectFit(ImageFit.Cover)Image($r('app.media.4')).objectFit(ImageFit.Cover)Image($r('app.media.5')).objectFit(ImageFit.Cover)}// 2. 设置尺寸.width('100%').height('100%')// 3. 定制方向和小圆点.vertical(true) // 纵向轮播.indicator(Indicator.dot() // 小圆点样式.color(Color.White).selectedColor(Color.Orange))
2.11控件-Scroll
// 如果希望内容溢出, 能够滚动Scroll() {Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical)-------------------------------常用属性----------------------------------// 如果希望内容溢出, 能够滚动Scroll() {Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical) // 设置滚动方向.scrollBar(BarState.Auto) // On一直显示 Off一直隐藏 Auto滑动显示.scrollBarColor(Color.Blue) // 滚动条颜色.scrollBarWidth(5) // 滚动条宽度.edgeEffect(EdgeEffect.Spring) // 滑动效果.onScroll((x, y) => {console.log('已经滑动的距离:', this.myScroll.currentOffset().yOffset)})
----------------------------控制器------------------------------------
Button('控制滚动条位置').margin(20).onClick(() => {
//划到某位置this.myScroll.scrollEdge(Edge.End)})Button('获取已经滚动的距离').onClick(() => {//当前滑动的位置const y = this.myScroll.currentOffset().yOffsetAlertDialog.show({message: `y: ${y}`})})
2.12 控件-Tabs
//基础用法
Tabs() {TabContent() {Text('首页内容') // 有且只能一个子组件}.tabBar('首页') // 配置导航TabContent() {Text('推荐内容') // 有且只能一个子组件}.tabBar('推荐')TabContent() {Text('发现内容') // 有且只能一个子组件}.tabBar('发现')TabContent() {Text('我的内容') // 有且只能一个子组件}.tabBar('我的')}-----------------------------常用属性---------------------------Tabs({ barPosition: BarPosition.Start }) {TabContent() {Text('首页内容') // 有且只能一个子组件}.tabBar('首页') // 配置导航TabContent() {Text('推荐内容') // 有且只能一个子组件}.tabBar('推荐')TabContent() {Text('发现内容') // 有且只能一个子组件}.tabBar('发现')TabContent() {Text('我的内容') // 有且只能一个子组件}.tabBar('我的')}.vertical(false) // 调整导航水平或垂直.scrollable(false) // 是否开启手势滑动.animationDuration(0) // 点击滑动的动画时间
----------------------------基础导航栏-----------------------------
@Entry
@Component
struct Index {// 准备状态, 存储激活的索引@State selectedIndex: number = 0@BuildermyBuilder (itemIndex: number, title: string, img: ResourceStr, selImg: ResourceStr) {// 如果激活的是自己, 图片/文本 都需要调整样式 → 需要区分不同的 tabBarColumn() {Image(itemIndex == this.selectedIndex ? selImg : img).width(30)Text(title).fontColor(itemIndex == this.selectedIndex ? Color.Red : Color.Black)}}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('购物车内容')}.tabBar(this.myBuilder(0, '购物车', $r('app.media.ic_tabbar_icon_2'), $r('app.media.ic_tabbar_icon_2_selected')))TabContent() {Text('我的内容')}.tabBar(this.myBuilder(1, '我的', $r('app.media.ic_tabbar_icon_3'), $r('app.media.ic_tabbar_icon_3_selected')))}.onChange((index: number) => {// console.log('激活的索引', index)this.selectedIndex = index}).animationDuration(0).scrollable(false)}
}
-----------------------小米中间有个图片导航栏---------------------------------
@Entry
@Component
struct Index {// 准备状态, 存储激活的索引@State selectedIndex: number = 0@BuildermyBuilder (itemIndex: number, title: string, img: ResourceStr, selImg: ResourceStr) {// 如果激活的是自己, 图片/文本 都需要调整样式 → 需要区分不同的 tabBarColumn() {Image(itemIndex == this.selectedIndex ? selImg : img).width(30)Text(title).fontColor(itemIndex == this.selectedIndex ? Color.Red : Color.Black)}}@BuildercenterBuilder () {Image($r('app.media.ic_reuse_02')).width(40).margin({ bottom: 10 })}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('首页内容')}.tabBar(this.myBuilder(0, '首页', $r('app.media.ic_tabbar_icon_0'), $r('app.media.ic_tabbar_icon_0_selected')))TabContent() {Text('分类内容')}.tabBar(this.myBuilder(1, '分类', $r('app.media.ic_tabbar_icon_1'), $r('app.media.ic_tabbar_icon_1_selected')))// 特殊形状的TabTabContent() {Text('活动内容')}.tabBar(this.centerBuilder())TabContent() {Text('购物车内容')}.tabBar(this.myBuilder(3, '购物车', $r('app.media.ic_tabbar_icon_2'), $r('app.media.ic_tabbar_icon_2_selected')))TabContent() {Text('我的内容')}.tabBar(this.myBuilder(4, '我的', $r('app.media.ic_tabbar_icon_3'), $r('app.media.ic_tabbar_icon_3_selected')))}.onChange((index: number) => {// console.log('激活的索引', index)this.selectedIndex = index}).animationDuration(0).scrollable(false)}
}
2.13控件-List
// 中间List() {ForEach(Array.from({ length: 20 }), () => {ListItem() {Row(){}.width('100%').height(100).backgroundColor(Color.Brown)}.padding(10)})}.width('100%').layoutWeight(1) // 让容器高度自适应.backgroundColor(Color.Orange).listDirection(Axis.Vertical) // 调整主轴方向(横向纵向).lanes(3, 5) // 调整 列数 和 间距.alignListItem(ListItemAlign.Center) // 列对齐方式.scrollBar(BarState.Auto) // Auto按需自动显示滚动条// .divider({// strokeWidth: 3, // 线宽// color: Color.Blue, // 颜色// startMargin: 10, // 左边线距离边缘的间隙// endMargin: 10 // 右边线距离边缘的间隙// })
2.14控件-Grid
3.1字符串转数字
let str1: string = '1.1'
let str2: string = '1.9'
let str3: string = '1.99a'
let str4: string = 'a'// 转数字类型
// 1. Number(变量) 原样转数字
console.log('Number', Number(str1)) // 1.1
console.log('Number', Number(str2)) // 1.9
console.log('Number', Number(str3)) // NaN
console.log('Number', Number(str4)) // NaN// 2. parseInt(变量) 去掉小数部分(取整)
console.log('parseInt', parseInt(str1)) // 1
console.log('parseInt', parseInt(str2)) // 1
console.log('parseInt', parseInt(str3)) // 1
console.log('parseInt', parseInt(str4)) // NaN// 3. parseFloat(变量) 保留小数部分
console.log('parseFloat', parseFloat(str1)) // 1.1
console.log('parseFloat', parseFloat(str2)) // 1.9
console.log('parseFloat', parseFloat(str3)) // 1.99
console.log('parseFloat', parseFloat(str4)) // NaN
3.2数字转字符串
// 数字通常用于计算, 字符串通常用于展示
let money: number = 10000
// 将数字转字符串, toString() toFixed()
// 1. 数据.toString() 原样转字符串
console.log('toString:', money.toString())// 2. 数据.toFixed(保留几位小数) 四舍五入
console.log('toFixed:', money.toFixed())
console.log('toFixed:', money.toFixed(2))
3.3点击事件
Button('点我,显示对话框').onClick(() => {// console.log('消息:', '你好点击事件')// 弹个框AlertDialog.show({message: '你好~ 这是个弹框'})})
3.5if-else
// 分支语句 - if 语句
// 1. 单分支 (满足条件, 就会执行一段代码)
// if (逻辑条件) {
// 条件成立时执行的代码
// }
// 2. 双分支 (满足条件, 会执行A代码, 不满足条件, 会执行B代码)
// if (逻辑条件) {
// 条件成立时执行的代码
// }
// else {
// 条件不成立时执行的代码
// }if (score >= 90) {console.log('奖励', '一台游戏机')
}
else {console.log('惩罚', '写个检讨, 分析出错原因')
}
3.6 switch
switch (fruit) {case '苹果':console.log('苹果价格:', '2.8元一斤')breakcase '香蕉':console.log('香蕉价格:', '5.5元一斤')breakcase '西瓜':console.log('西瓜价格:', '1.5元一斤')breakdefault:console.log('提示:', '尊敬的用户, 该水果不存在')
}
3.7 三元表达式
// 三元条件表达式
// 语法: 条件 ? 条件成立执行的表达式 : 条件不成立执行的表达式let num1: number = 40
let num2: number = 30// let max: number = num1 > num2 ? num1 : num2
// console.log('三元条件表达式', max)let res: number = num1 > num2 ? 3 * 5 : 2 + 6
console.log('三元条件表达式', res)
3.8 条件渲染
// 条件渲染: 不同的条件, 控制不同的UI界面展示Column() {if (this.age < 18) {Text('未成年, 18岁以下')}else if (this.age < 60) {Text('成年人, 18~60岁')}else {Text('老年人, 60+')}Button('长大').onClick(() => {this.age += 5})Text(`当前年纪: ${this.age}`)}
3.9 while循环
let i: number = 1
let sum: number = 0 // 存储累加的结果while (i <= 10) {console.log('需要累加的数字:', i)// 每次执行下面这行代码, 就会进行一次累加, 并且更新累加的结果sum = sum + ii++
}
3.10 for循环
// 1-10的和, 从1开始,循环到10
let sum = 0
for (let i: number = 1; i <= 10; i++) {console.log('for', i)sum = sum + i // sum += i
}
console.log('求和', sum)--------------------------------------------
// 退出循环:
// 1. break: 终止整个循环 (后面的循环不执行了)
// 2. continue: 退出当前这一次循环, 继续执行下一次循环 (包子当前这个不吃了, 吃下一个)for (let i: number = 1; i <= 8; i++) {if (i == 5) {console.log('拿起了第5个包子, 发现坏了')// 当前这次循环不继续执行了, 继续执行下一次循环continue}console.log('吃包子:', `第${i}个`)-------------------------写法2---------------------------
for (let item of names) {console.log('数组中的每一项', item)
}-------------------------写法3---------------------------
ForEach(this.historyArr, (item: Resp, index: number) => {})
8.路由使用
//1.引入路由
import router from '@ohos.router'//2.使用跳转router.pushUrl({url: "pages/Show"})
9.延迟
//延迟跳转setTimeout(() => {//跳转到数据展示页面router.pushUrl({url: "pages/Show"})},2000)
4.1布局-grid布局
// Grid布局的基本使用: 规则的行列布局中非常常见, 3行4列Grid() {ForEach([1,2,3,4,5,6,7,8,9,10,11,12], () => {GridItem() {Column() {}.width('100%').height('100%').backgroundColor(Color.Green).border({ width: 1 })}})}.columnsTemplate('1fr 1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr').columnsGap(5).rowsGap(5).width('100%').height(500).backgroundColor(Color.Pink)
4.2 Flex布局
// Flex默认主轴水平往右,交叉轴垂直往下 → Row// 1. 主轴方向// direction: FlexDirection.Row / Column// 2. 主轴对齐方式// justifyContent: FlexAlign.SpaceAround// 3. 交叉轴对齐方式// alignItems: ItemAlign.Stretch / Start / Center / End// 单行或者单列的情况,优先还是使用线性布局(本质基于Flex设计的,且还做了性能优化)// Flex布局:伸缩布局。当子盒子的总和溢出父盒子,默认进行压缩显示。// 4. 换行 wrap// FlexWrap.Wrap 换行// FlexWrap.NoWrap 不换行Flex({direction: FlexDirection.Column,justifyContent: FlexAlign.SpaceBetween,alignItems: ItemAlign.Start,wrap: FlexWrap.Wrap}) {Text().width(80).height(80).backgroundColor(Color.Pink).border({ width: 1, color: Color.Blue })Text().width(80).height(80).backgroundColor(Color.Pink).border({ width: 1, color: Color.Blue })Text().width(80).height(80).backgroundColor(Color.Pink).border({ width: 1, color: Color.Blue })}.width('100%').height(600).backgroundColor('#5f9a5c')
4.3 层叠布局
// 层叠布局Stack({alignContent: Alignment.Bottom}) {Text('大儿子').width(250).height(250).backgroundColor(Color.Green).zIndex(3)Text('二儿子').width(150).height(150).backgroundColor(Color.Orange).zIndex(4)Text('三儿子').width(50).height(50).backgroundColor(Color.Yellow).zIndex(5)}.width(300).height(600).backgroundColor(Color.Pink)
5.1数据-动态渲染
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {url: stringcount: number
}@Entry
@Component
struct Index {// 2. 基于接口, 准备数据@State images: ImageCount[] = [{ url: 'app.media.bg_00', count: 0 },{ url: 'app.media.bg_01', count: 1 },{ url: 'app.media.bg_02', count: 2 },{ url: 'app.media.bg_03', count: 3 },{ url: 'app.media.bg_04', count: 4 },{ url: 'app.media.bg_05', count: 5 }]build() {Column() {Grid() {ForEach(this.images, (item: ImageCount, index: number) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 14,badgeSize: 20,badgeColor: '#fa2a2d'}}) {Image($r(item.url)).width(80)}}})}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr').width('100%').height(300).margin({ top: 100 })Button('立即抽卡').width(200).backgroundColor('#ed5b8c').margin({ top: 50 })}}
}
5.2 对象转字符串
JSON.stringify(err)
6.1 动画-动画特效
// 定义接口 (每个列表项的数据结构)
interface ImageCount {url: stringcount: number
}// 需求1: 遮罩层显隐 透明度opacity 0-1 层级zIndex -1~99
// 需求2: 图片缩放 缩放scale 0-1@Entry
@Component
struct Index {// 基于接口, 准备数据@State images: ImageCount[] = [{ url: 'app.media.bg_00', count: 0 },{ url: 'app.media.bg_01', count: 1 },{ url: 'app.media.bg_02', count: 2 },{ url: 'app.media.bg_03', count: 3 },{ url: 'app.media.bg_04', count: 4 },{ url: 'app.media.bg_05', count: 5 }]// 控制遮罩的显隐@State maskOpacity: number = 0 // 透明度@State maskZIndex: number = -1 // 显示层级// 控制图片的缩放@State maskImgX: number = 0 // 水平缩放比@State maskImgY: number = 0 // 垂直缩放比build() {Stack() {// 初始化的布局结构Column() {Grid() {ForEach(this.images, (item: ImageCount, index: number) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 14,badgeSize: 20,badgeColor: '#fa2a2d'}}) {Image($r(item.url)).width(80)}}})}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr').width('100%').height(300).margin({ top: 100 })Button('立即抽卡').width(200).backgroundColor('#ed5b8c').margin({ top: 50 }).onClick(() => {// 点击时, 修改遮罩参数, 让遮罩显示this.maskOpacity = 1this.maskZIndex = 99// 点击时, 图片需要缩放this.maskImgX = 1this.maskImgY = 1})}.width('100%').height('100%')// 抽卡遮罩层 (弹层)Column({ space: 30 }) {Text('获得生肖卡').fontColor('#f5ebcf').fontSize(25).fontWeight(FontWeight.Bold)Image($r('app.media.img_00')).width(200)// 控制元素的缩放.scale({x: this.maskImgX,y: this.maskImgY}).animation({duration: 500})Button('开心收下').width(200).height(50).backgroundColor(Color.Transparent).border({ width: 2, color: '#fff9e0' }).onClick(() => {// 控制弹层显隐this.maskOpacity = 0this.maskZIndex = -1// 图像重置缩放比为 0this.maskImgX = 0this.maskImgY = 0})}.justifyContent(FlexAlign.Center).width('100%').height('100%')// 颜色十六进制色值,如果是八位,前两位,就是透明度.backgroundColor('#cc000000')// 设置透明度.opacity(this.maskOpacity).zIndex(this.maskZIndex)// 动画 animation, 当我们元素有状态的改变,可以添加animation做动画.animation({duration: 200})}}
}
7. 模块化-导入,导出模块
// 路径: 查找文件时, 从起点到终点的路线
// 相对路径: 从当前文件出发查找目标文件
// → 找上一级 ../
// → 同级目录 ./// 1. 默认导入
// import result from '../tools/module1'
// import fn from './module2'
// console.log('module1中的数据', JSON.stringify(result))
// fn()// 2. 按需导入
// import { name1, price, sayHi as sayHello } from '../tools/module3'
// console.log('module3中的数据', name1, price)
// sayHello()// 3. 全部导入
import * as Module3 from '../tools/module3'
console.log('全部的数据', Module3.name1)
console.log('全部的数据', Module3.price2)
Module3.sayHi()--------------------------默认导出------------------
interface Person {name: stringage: number
}// 一个ets文件, 就是一个模块, 每个模块之间独立
let num: number = 10
let person: Person = {name: 'jack',age: 18
}// 默认导出 (导出一个值)
export default person--------------------------按需导出------------------------
// 按需导出
// 多个特性, 逐个 export 按需导出
// export let name1: string = '刘备'
// export let price: number = 9.98
// export let sayHi = () => {
// console.log('打招呼')
// }let name1: string = '刘备'
let name2: string = '张飞'
let name3: string = '关羽'let price: number = 9.98
let price2: number = 10.1let sayHi = () => {console.log('打招呼')
}
let run = () => {console.log('跑步')
}// 一次性将多个特性, 进行导出
export {name1, name2, name3,price, price2,sayHi, run
}
8.0 注解-@Entry
8.1 注解-@Extend 特定组件继承
// @Extend(组件名)
// function 函数名 (参数, 参数2) {
//
// }@Extend(Text)
function textFn () {.fontSize(20).fontWeight(FontWeight.Bold)
}@Extend(Text)
function bannerItem (bgColor: ResourceColor, msg: string) {.textAlign(TextAlign.Center).backgroundColor(bgColor).fontColor(Color.White).fontSize(30).onClick(() => {AlertDialog.show({message: msg})})
}----------------------------调用------------------------------Text(this.message).textFn()Swiper() {Text('1').bannerItem(Color.Orange, '轮播图1号')Text('2').bannerItem(Color.Brown, '轮播图2号')Text('3').bannerItem(Color.Green, '轮播图3号')}.width('100%').height(160)
8.2注解-@Styles 通用组件设置值
// 1. 全局定义
@Styles function commonStyles () {.width(100).height(100)
}@Entry
@Component
struct StylesDemo {@State message: string = '@styles';@State bgColor: ResourceColor = Color.Gray// 2. 组件内定义(才能通过this访问到自己的状态)@Styles setBg() {.backgroundColor(this.bgColor).onClick(() => {this.bgColor = Color.Green})}build() {Column({ space: 10 }) {Text(this.message).fontColor(Color.White).commonStyles().setBg()Column() {}.commonStyles().setBg()Button('按钮').commonStyles().setBg()}.width('100%').height('100%')}}
8.3注解-@Builder 构建一个全局组件
// 全局 Builder
@Builder
function navItem(icon: ResourceStr, txt: string) {Column({ space: 10 }) {Image(icon).width('80%')Text(txt)}.width('25%').onClick(() => {AlertDialog.show({message: '点了' + txt})})
}@Entry
@Component
struct BuilderDemo {@State message: string = '@Builder';@BuildernavItem(icon: ResourceStr, txt: string) {Column({ space: 10 }) {Image(icon).width('80%')Text(txt)}.width('25%').onClick(() => {AlertDialog.show({message: '点了' + txt + this.message})})}build() {Column({ space: 20 }) {Text(this.message).fontSize(30)Row() {Row() {navItem($r('app.media.ic_reuse_01'), '阿里拍卖')navItem($r('app.media.ic_reuse_02'), '菜鸟')this.navItem($r('app.media.ic_reuse_03'), '巴巴农场')this.navItem($r('app.media.ic_reuse_04'), '阿里药房')}}}.width('100%').height('100%')}}
8.4 注解-@Component 自定义组件
自定义组件生命周期
@Component
struct MyCom {@State count: number = 1build() {Row() {Text(this.count.toString()).fontColor(Color.White).margin(10)Button('按钮').onClick(() => {this.count++})}}
}@Component
struct MyHeader {build() {Row() {Text('我是头部').fontColor(Color.White)}.width('100%').height(50).backgroundColor(Color.Brown)}
}@Component
struct MyMain {build() {Column() {// 将相同的业务逻辑, 封装成一个通用的组件MyCom()MyCom()MyCom()}.layoutWeight(1).width('100%').backgroundColor(Color.Gray)}
}@Component
struct MyFooter {build() {Row() {Text('我是底部')}.width('100%').height(50).backgroundColor(Color.Green)}
}@Entry
@Component
struct Index {build() {Column() {MyHeader()MyMain()MyFooter()}}
}---------------------------------------1.导出组件------------------
//加入这个@Preview可以预览页面@Preview
@Component
export struct HelloCom {build() {Row() {Text('自定义组件')Button('按钮')}.width(200).height(50).backgroundColor(Color.Orange)}
}
-----------------------------------2.导入组件----------------------------
import { HelloCom } from '../components/HelloCom'@Entry
@Component
struct Index {build() {Column() {HelloCom().width(250).height(60).backgroundColor(Color.Gray).onClick(() => {AlertDialog.show({message: '测试点击'})})}}
}--------------------------成员变量函数重新赋值----------------------通俗的讲就是带等号的重新赋值@Component
struct MyPanel {// 成员变量 - 数据title: string = '默认的大标题'extra: string = '查看更多 >'// 成员变量 - 函数 - 可以外部传入覆盖的getMore = () => {AlertDialog.show({message: '查看更多'})}// 成员函数 - 不可以外部传入覆盖sayHi() {AlertDialog.show({message: '打招呼, 你好'})}build() {Column() {Row() {Text(this.title).fontSize(18)Text(this.extra).fontSize(18).onClick(() => {this.getMore()})}.width('100%').justifyContent(FlexAlign.SpaceBetween)Row() {Text('内容部分').fontSize(18)Button('按钮').onClick(() => {this.sayHi()})}.padding(20)}.padding(10).width('100%').height(200).margin({ bottom: 20 }).borderRadius(10).backgroundColor(Color.White)}
}@Entry
@Component
struct Index {build() {Column() {MyPanel({title: '我的订单',extra: '全部订单 > ',getMore() {AlertDialog.show({message: '点击了全部订单'})}})MyPanel({title: '小米有品重酬',extra: '7款重酬中 >',getMore() {AlertDialog.show({message: '查看7款重酬'})}})}.width('100%').height('100%').backgroundColor('#ccc').padding(20)}
}
8.5 注解-@BuilderParam 可以让自定义组件外部传递UI,相当于vue的插槽
@Component
struct MyPanel {// 成员变量 - 数据title: string = '默认的大标题'extra: string = '查看更多 >'// 成员变量 - 函数 - 可以外部传入覆盖的getMore = () => {AlertDialog.show({message: '查看更多'})}// 成员函数 - 不可以外部传入覆盖sayHi() {AlertDialog.show({message: '打招呼, 你好'})}@BuilderParam ContentBuilder: () => void = this.defaultBuilder@Builder defaultBuilder () {Text('默认文本')}build() {Column() {Row() {Text(this.title).fontSize(18)Text(this.extra).fontSize(18).onClick(() => {this.getMore()})}.width('100%').justifyContent(FlexAlign.SpaceBetween)Row() {// 这里的结构不能写死, 需要通过 BuilderParam 来进行构建this.ContentBuilder()}.padding(20)}.padding(10).width('100%').height(200).margin({ bottom: 20 }).borderRadius(10).backgroundColor(Color.White)}
}@Entry
@Component
struct Index {build() {Column() {MyPanel({title: '我的订单',extra: '全部订单 > ',getMore() {AlertDialog.show({message: '点击了全部订单'})}}) {Column() {Text('我是订单 - 相关的文本')Text('我是订单 - 相关的文本')Text('我是订单 - 相关的文本')}}MyPanel({title: '小米有品重酬',extra: '7款重酬中 >',getMore() {AlertDialog.show({message: '查看7款重酬'})}}) {Column() {Button('我是小米重酬的按钮')Button('我是小米重酬的按钮')Button('我是小米重酬的按钮')}}}.width('100%').height('100%').backgroundColor('#ccc').padding(20)}
}----------------------------多BuilderParam-----------------
@Component
struct MyCard {@BuilderParam tBuilder: () => void = this.tDefaultBuilder@BuilderParam cBuilder: () => void = this.cDefaultBuilder@Builder tDefaultBuilder () {Text('我是默认的大标题')}@Builder cDefaultBuilder () {Text('我是默认的内容')}build() {// 卡片组件Column() {// 标题部分Row() {this.tBuilder()}.height(30).width('100%').border({ color: '#ccc', width: { bottom: 1 }}).padding({ left: 10 })// 内容部分Row() {this.cBuilder()}.width('100%').padding(10)}.width('100%').height(100).backgroundColor(Color.White).borderRadius(10).justifyContent(FlexAlign.Start)}
}@Entry
@Component
struct Index {@Builder ftBuilder () {Text('我是传入的大标题结构')}@Builder fcBuilder () {Text('我是内容部分')Text('我是内容部分')Text('我是内容部分')}build() {Column({ space: 10 }) {MyCard()MyCard({tBuilder: this.ftBuilder,cBuilder: this.fcBuilder})}.width('100%').height('100%').padding(20).backgroundColor('#ccc')}
}
8.6注解-@State 状态变量
// 注意点:
// 1. 普通变量, 只能在初始化时渲染, 后续变化了, 也不会引起更新
// 2. 状态变量, 被装饰器修饰, 值的改变, 会 [自动] 引起 界面的刷新// 组件外的[普通变量] 不需要this即可访问
let myName: string = '吕布'@Entry
@Component
struct Index {// 组件内的[普通变量] this.xxxmyAge: number = 18// 组件内的[状态变量] this.xxx@State myMsg: string = 'hello 黑马'build() {Column() {Text(myName).onClick(() => {myName = '貂蝉'console.log('myName', myName)})Text(this.myAge.toString()).onClick(() => {this.myAge = 200console.log('myAge', this.myAge)})Text(this.myMsg).onClick(() => {this.myMsg = '你好 状态'})}}
}-----------------------复杂类型更改方式-----------------------
//这么更改
//this.person.car = {// name: '老爷车'// }interface Car {name: string
}
interface Person {name: stringcar: Car
}const obj: Person = {name: 'zs',car: {name: '小黄车'}
}
console.log('查看第一层属性', Object.keys(obj))@Entry
@Component
struct Index {// 状态变量// 1. string number boolean 可以直接监视到变化@State message: string = 'hello world'// 2. 复杂类型 object class, 第一层随便改, 嵌套需要进行整个嵌套对象的替换@State person: Person = {name: 'jack',car: {name: '宝马车'}}build() {Column() {Text(this.message).fontSize(20)Button('改message').onClick(() => {this.message = '你好'})Text(JSON.stringify(this.person))Button('改person').onClick(() => {// this.person = {// name: 'amy',// car: {// name: '保时捷'// }// }this.person.name = 'tony'// 如果不是对象的第一层属性, 修改时, 需要修改整个嵌套的对象this.person.car.name = '小火车'// console.log('car name', this.person.car.name)this.person.car = {name: '老爷车'}})}}
}
8.7 注解-@Prop父传子,让值变化
//@Prop加了这个后,父组件更改这个值,子组件也会跟着变化@Component
struct SonCom {// 保证父组件的数据变化了, 能够往下响应式的更新@Prop sCar: string = ''changeCar = (newCar: string) => {}build() {Column() {Text(`子组件 ${this.sCar}`)Button('换车').onClick((event: ClickEvent) => {// 1. prop传值 → 单向传递// 子组件, 可以修改到 prop 传值, 但是修改的更新不会同步到父组件// 通常不太会直接修改 prop 传值, 父组件的状态一旦变化, 会自动向下同步// 修改就被覆盖了// this.sCar = '小黄车'// 2. 如果实在想更新, 希望保证父子同步 => 调用父组件传递过来的方法// 如果没有写箭头函数, 意味着, this 指向 调用者, 而此处执行环境 this → 子组件this.changeCar('蹦蹦车')})}.padding(20).backgroundColor(Color.Orange)}
}@Entry
@Component
struct FatherCom {@State fCar:string = '劳斯莱斯'build() {Column() {Text(`父组件 - ${this.fCar}`)Button('换车').onClick(() => {this.fCar = '三轮车'})SonCom({sCar: this.fCar,// 这里必须要用箭头函数, 否则会有 this 指向的问题// 使用箭头函数的好处, 可以使用外部环境的 this, 不受传递过去后的执行环境影响// 希望此处 this 指向 父组件changeCar: (newCar: string) => {this.fCar = newCar}})}.padding(50).backgroundColor(Color.Pink)}
}
8.8注解-@Link 父传子 子传父,数据双向同步
interface Person {name: stringage: number
}@Entry
@Component// 父组件
struct KnowledgePage {@State count: number = 0@State person: Person = {name: 'zs',age: 18}build() {Column() {Text('父组件').fontSize(30)Text(this.count.toString())Text(JSON.stringify(this.person))Button('修改数据').onClick(() => {this.count++})SonComponent({count: this.count,person: this.person})}.padding(10).height('100%').backgroundColor('#eee').width('100%').alignItems(HorizontalAlign.Center).padding({ top: 100 })}
}@Component// 子组件
struct SonComponent {@Link count: number@Link person: Person// 编写 UIbuild() {Column({ space: 20 }) {Text('我是子组件').fontSize(20)Text(this.count.toString())Text(JSON.stringify(this.person))Column() {Button('修改数据').onClick(() => {// this.count++this.person.age++})}}.backgroundColor('#a6c398').alignItems(HorizontalAlign.Center).width('80%').margin({ top: 100 }).padding(10).borderRadius(10)}
}
8.9注解- @Consume和@Provide父与子孙后代简单数据同步
interface Car {name: stringbrand: string
}@Entry
@Component// 顶级组件
struct RootComponent {@Provide themeColor: string = 'yellow'@Provide car: Car = {name: '小黄',brand: '美团'}build() {Column() {Text('顶级组件').fontSize(30).fontWeight(900)Text(this.themeColor)Text(JSON.stringify(this.car))// 二级组件ParentComponent()ParentComponent()}.padding(10).height('100%').backgroundColor('#ccc').width('100%').alignItems(HorizontalAlign.Center).padding({ top: 100 })}
}@Component// 二级组件
struct ParentComponent {@Consume themeColor: string// 编写 UIbuild() {Column({ space: 20 }) {Text('我是二级组件').fontSize(22).fontWeight(900)Text(this.themeColor)// 内层子组件SonComponent()}.backgroundColor('#a6c398').alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}@Component// 内层组件
struct SonComponent {@Consume themeColor: string@Consume car: Car// 编写 UIbuild() {Column({ space: 20 }) {Text('我是内层组件' + this.themeColor).fontSize(20).fontWeight(900).onClick(() => {// this.themeColor = 'orange'this.car.name = '小绿'})Text(JSON.stringify(this.car))}.backgroundColor('#bf94e4').alignItems(HorizontalAlign.Center).width('90%').margin({ top: 50 }).padding(10).borderRadius(10)}
}
8.10注解- @Observed和@ObjectLink父与子孙后代复杂数据同步(多层数据)
interface IPerson {id: numbername: stringage: number
}@Observed
class Person {id: numbername: stringage: numberconstructor(obj: IPerson) {this.id = obj.idthis.name = obj.namethis.age = obj.age}
}@Entry
@Component
struct ObservedAndLink {@State personList: Person[] = [new Person({id: 1,name: '张三',age: 18}),new Person({id: 2,name: '李四',age: 19}),new Person({id: 3,name: '王五',age: 20})]build() {Column({ space: 20 }) {Text('父组件').fontSize(30)List({ space: 10 }) {ForEach(this.personList, (item: Person, index: number) => {ItemCom({info: item,addAge: () => {// 修改嵌套的数据 => 普通的情况, 监视不到更新item.age++ // 如果能监视到AlertDialog.show({message: JSON.stringify(this.personList)})// this.personList.splice(index, 1, item) // 无需手动替换更新}})})}}.backgroundColor('#cbe69b').width('100%').height('100%').padding(20)}
}@Component
struct ItemCom {@ObjectLink info: PersonaddAge = () => {}build() {ListItem() {Row({ space: 10 }) {Text('姓名:' + this.info.name)Text('年龄:' + this.info.age)Blank()Button('修改数据').onClick(() => {// this.addAge()this.info.age++})}.backgroundColor(Color.Pink).padding(10).width('100%')}}
}
9.1 类
// 类
// class 类名 {
// 字段名:类型 = 初始值
// 字段名?:类型
// }class Cat {name: string = 'Tom'foods?: string
}
// 基于类, 创建对象
let p: Cat = new Cat()
console.log('姓名:', p.name.length)p.foods = '小黄鱼'
console.log('食物:', p.foods?.length)@Entry
@Component
struct Index {build() {}
}
-----------------构造函数语法--------------------
// 构造函数语法
// class Food {
// name: string
// price: number
// // 希望不同实例, 有不同的字段初始值 → 构造函数
// constructor(name: string, price: number) {
// this.name = name
// this.price = price
// }
// }
// let f1: Food = new Food('西兰花', 20)
// console.log('名称:', f1.name, '价格:', f1.price)
//
// let f2: Food = new Food('土豆炖鸡块', 28)
// console.log('名称:', f2.name, '价格:', f2.price)interface IFood {name: stringprice: numberdesc: string
}class Food {name: stringprice: numberdesc: string// 希望不同实例, 有不同的字段初始值 → 构造函数constructor(paramsObj: IFood) {this.name = paramsObj.namethis.price = paramsObj.pricethis.desc = paramsObj.desc}
}
let p1: Food = new Food({name: '西兰花',desc: '好吃',price: 20
})
let p2: Food = new Food({name: '黄瓜炒鸡蛋',desc: '清爽',price: 12
})
console.log('名称', p1.name)
console.log('名称', p2.name)@Entry
@Component
struct Index {build() {}
}------------------------定义方法------------------------
// 类 → 定方法
class Person {name: stringage: numberconstructor(name: string, age: number) {this.name = namethis.age = age}// 跟xxx打招呼, 还要自我介绍sayHi(yourName: string) {// 通过this可以访问到创建出来的实例对象console.log(`hello, ${yourName}, 我是${this.name}`)}sing(): string {return '稻香'}
}
let p1:Person = new Person('凹凸曼', 18)
p1.sayHi('小怪兽')let p2:Person = new Person('大灰狼', 5)
p2.sayHi('小绵羊')@Entry
@Component
struct Index {build() {}
}
----------------------------静态属性和静态方法------------------------
// 静态属性 和 静态方法
class Robot {static version: string = 'v2.0'static getRandom(): number {return Math.random()}
}
console.log('Robot类的版本', Robot.version)
console.log('工具方法:', Robot.getRandom())
------------------------------类的继承-----------------------------------
// 父类 子类
// 人类 学生, 老师, 工人
class Person {name: stringage: numberconstructor(name: string, age: number) {this.name = namethis.age = age}sayHi() {console.log('大家好~', this.name, this.age)}
}class Student extends Person {grade: stringconstructor(name: string, age: number, grade: string) {// 父类中的构造函数, 此时需要我们手动调用 super() 构造函数, super.方法名(), super.属性名super(name, age)// 完成自己属性的初始化this.grade = grade}study () {console.log('我是学生, 我爱学习~')}// 子类中想要重写父类中的方法, 只需提供同名的方法即可sayHi(): void {super.name // 获取父类的属性super.age // 获取父类的属性super.sayHi() // 调用了父类的方法console.log('hello, nice to meet you'); // 扩展了自己的特性}
}
let s1: Student = new Student('小明', 18, '五年级')
s1.sayHi() // 调用重写的sayHi方法// s1.study() // 调用自己的study方法
// console.log(s1.grade) // 访问自己的grade属性let s2: Student = new Student('小蓝', 18, '三年级')
// console.log(s2.grade)// class Teacher extends Person {
// }
// let t1: Teacher = new Teacher('李老师', 35)
// t1.sayHi() // 调用父类的sayHi方法
//
//
// class Worker extends Person {
// }
-----------------判断是否是这个类-------------------------
class Person {}
class Student extends Person {}
class Worker extends Person {}let s: Student = new Student()
console.log('判断结果:', s instanceof Student)
console.log('判断结果:', s instanceof Person)
console.log('判断结果:', s instanceof Worker)interface IObj {}
// 判断一个变量是否存的是数组
let temp: IObj = {}
console.log('是否是数组', temp instanceof Array)---------------------修饰符 readonly --------------------------------
// 修饰符 readonly
class Cat {name: stringage: numberreadonly legs: number = 4constructor(name: string, age: number) {this.name = namethis.age = age}
}
let c1 = new Cat('小花', 2)
c1.name = '小美'
// c1.legs = 6 // 不能修改
console.log('姓名:', c1.name)------------------修饰符 private----------------
// class Person {
// private name: string = ''
// private age: number = 0
// desc: string = '描述'
// }
// let p = new Person()
// console.log('实例访问:', p.name) // 无法再外部访问私有数据// class Student extends Person {
// sayHi () {
// console.log('访问私有的数据:', super.name) // 私有数据无法再(子类)访问
// }
// }---------------------修饰符 protected和public--------------------------------
class Person {protected name: stringprotected age: numberdesc: string = '描述'// 类的内容, 无论是私有还是保护, 都是可以访问的constructor(name: string, age: number) {this.name = namethis.age = age}
}
let p = new Person('小王', 18)
// console.log('实例访问:', p.name) // 无法在外部, 访问受保护的数据class Student extends Person {sayHi () {console.log('访问私有的数据:', super.name) // 保护的数据可以在子类访问}
}
10.1 接口
------------------------------接口的继承---------------
interface IAnimal {name: stringage: number
}
interface ICat extends IAnimal {hair: string
}
interface IDog extends IAnimal {color: string
}
let dog1: IDog = {name: '小泰迪',age: 2,color: '棕色'
}---------------------------接口的实现-----------------------
// 接口实现: 定义一个接口, 约束类 => 类需要按照接口的要求, 实现类的主体
interface IDog {name: stringage: numberjump: () => void
}// 基于接口, 实现类
class Dog implements IDog {name: stringage: numberdesc: stringconstructor(name: string, age: number, desc: string) {this.name = namethis.age = agethis.desc = desc}jump() {}
}
let dog: Dog = new Dog('小飞', 2, '是一只非常帅气的二哈')
dog.jump()function 函数名<Type>(temp:Type):Type{return temp
}
11.1泛型
// 泛型: 广泛的类型 => 类型可以作为参数传递过来, 类型是[可变]的
// function 函数名<Type> (形参: Type): Type {
// return 形参
// }// 封装了一个函数: 传入什么样的参数, 就立刻返回什么样的参数
function fn<T> (param: T) : T {return param
}
fn<string>('abc')
fn<number>(123)
fn<boolean>(true)
fn<number[]>([1, 2, 3, 4, 5])// 会默认根据传参, 进行类型推断, 动态的配置 T 类型参数 的值
fn(true)
fn([1, 2, 3, 4, 5])// 练习1: 定义函数, 参数是数组(存的类型不定), 返回数组的长度
function getLength<T> (arr: T[]) : number {return arr.length
}
console.log('', getLength<number>([1, 2, 3]))
console.log('', getLength<string>(['1', 'aa', 'bb', 'cc']))// 练习2: 定义函数, 参数是数组(存的类型不定), 返回数组的最后一项
function getLast<T> (arr: T[]) : T {return arr[arr.length - 1]
}
console.log('', getLast<number>([1, 2, 3, 4, 99]))
console.log('', getLast<string>(['a', 'b', 'c']))------------------------------------------泛型的约束----------------
// 泛型约束: 给传递的类型参数, 添加限制
interface ILength {length: number
}
function fn<T extends ILength>(param: T) {console.log('', param.length)
}fn<string>('abc')
fn<number[]>([1, 2, 3])class Desk {length = 2
}
let d = new Desk()----------------------------多个泛型变量------------------------------
// 多个泛型变量 => 传递多个类型参数
function fn<T1, T2> (param1: T1, param2: T2) {console.log('参数1', param1)console.log('参数2', param2)
}
fn<string, boolean>('abc', true)
fn<number, string>(123, 'abc')
fn<string[], number[]>(['a', 'b'], [1, 2])fn<Desk>(d)--------------------------泛型接口------------------------------------
// 泛型接口
interface IdFunc<T> {// 约定有两个方法 (id类型不定, string number)// 1. 传入 id 值, 就返回 id 值// 2. 返回一个 ids 数组id: (value: T) => Tids: () => T[]
}let obj: IdFunc<number> = {id(value: number) {return value},ids() {return [1, 2, 3]}
}let obj2: IdFunc<string> = {id(value: string) {return value},ids() {return ['001', '002', '003']}
}
---------------------------泛型类--------------------------------------
// 泛型类: 定义类的时候, 配合泛型一起定义
class Person <T>{id: Tconstructor(id: T) {this.id = id}getId (): T {return this.id}
}
let p: Person<number> = new Person<number>(10)
let p2: Person<string> = new Person<string>('abc')
12.页面跳转
import { router } from '@kit.ArkUI';@Entry
@Component
struct LoginPage {@State message: string = '登陆页';build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).onClick(() => {router.pushUrl({url: 'pages/Index'})})}.width('100%')}.height('100%')}
}----------------------------调用方法 - 替换跳转(无法返回)------------------
router.replaceUrl({
url:'页面地址'
})
----------------------------调用方法 - 返回()---------------------------
router.back()-----------------------------获取页面栈长度------------------------------
router.getLength()
----------------------------清空页面栈-------------------------------------
router.clear()-----------------------------路由模式------------------------------------
路由 – 4. 路由模式
路由提供了两种不同的跳转模式
1. Standard:无论之前是否添加过,一直添加到页面栈【默认常用】
2. Single:如果目标页面已存在,会将已有的最近同url页面移到栈顶【看情况使用】router.pushUrl({url: 'pages/DetailPage'}, router.RouterMode.Single)-----------------------------跳转携带参数----------------------
//发送参数router.pushUrl({url: 'pages/Index',params: {username: this.username,msg: '测试消息'}})
//接收参数// 一进入页面, 就会执行的函数 => 生命周期函数aboutToAppear(): void {console.log('传递过来的数据', JSON.stringify(router.getParams()))const params = router.getParams() as ParamsObjthis.myName = params.username}
13.1 自定义组件-生命周期
aboutToAppear(): void {}aboutToDisappear(): void {}onPageShow(): void {}onPageHide(): void {}onBackPress(): boolean | void {}build() {}
13.2自定义组件-页面控制
14.2 stage模型
14.2 stage模型-全局配置信息
14.3 UIAbility 的添加 和 设置启动(相当于微信里的微信小程序,从最近任务打开,可以切换是聊天还是操作小程序)
14.4设置主启动Ability
"exported": true,"skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}]
14.4 UIAbility 组件的生命周期
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';export default class ApplicationAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');}onDestroy(): void {hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');}onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');windowStage.loadContent('pages/Index', (err) => {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');});}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}onForeground(): void {// Ability has brought to foregroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');}onBackground(): void {// Ability has back to backgroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');}
}
14.3配置-启动页配置
14.4 同模块唤醒Ability
context = getContext(this) as common.UIAbilityContext // 1. 准备 want (参数信息)let wantInfo: Want = {deviceId: '', // 空表示本设备bundleName: 'com.example.part4demo', // AppScope/app.json 确认moduleName: 'entry', // 模块名abilityName: 'TwoAbility', // src/main/module.json5parameters: {info: '来自entryAbility'}}// 2. 利用context startAbility 调起 UIAbility// 返回一个promise对象this.context.startAbility(wantInfo).then(() => {console.log('startAbility 成功')}).catch((error: BusinessError) => {console.log('启动Ability 失败', error)})
14.5 不同模块唤醒Ability
context = getContext(this) as common.UIAbilityContext// 1. 准备 want (参数信息)let wantInfo: Want = {deviceId: '', // 空表示本设备bundleName: 'com.example.part4demo', // AppScope/app.json 确认moduleName: 'TestModule', // 模块名abilityName: 'TestModuleAbility', // src/main/module.json5parameters: {info: '来自entryAbility'}}// 2. 利用context startAbility 调起 UIAbility// 返回一个promise对象this.context.startAbility(wantInfo).then(() => {console.log('startAbility 成功')}).catch((error: BusinessError) => {console.log('启动Ability 失败', error)})