|
|
# 构建应用
|
|
|
|
|
|
##### 字符串拼接
|
|
|
|
|
|
```
|
|
|
//直接用+号拼接
|
|
|
'hello' + 'world' = 'helloworld'
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
##### 占位符
|
|
|
|
|
|
```
|
|
|
//模板字符串``支持以${变量名}形式的占位符
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 类型转换
|
|
|
|
|
|
##### 字符串转数字
|
|
|
|
|
|
- Number()直接转数字,失败返回NaN
|
|
|
- parseInt()去小数转数字,失败返回NaN
|
|
|
- parseFloat()保留小数,失败返回NaN
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 数字转字符串
|
|
|
|
|
|
- toString() 直接转字符串
|
|
|
- toFixed() 四舍五入后转字符串,可设置保留几位小数
|
|
|
|
|
|
```
|
|
|
num.toString()
|
|
|
num.toFixed(保留小数位数)
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 交互
|
|
|
|
|
|
##### 点击事件
|
|
|
|
|
|
```
|
|
|
//点击弹出弹框
|
|
|
Button('点击演示')
|
|
|
.onClick(()=>{
|
|
|
console.log('按钮被点击')
|
|
|
AlertDialog.show({
|
|
|
message: '弹出'
|
|
|
})
|
|
|
})
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 状态管理
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
//设置状态变量后,该变量更新后,界面会重新渲染
|
|
|
@State i: number = 0
|
|
|
build(){
|
|
|
Row(){
|
|
|
Column(){
|
|
|
this.i = 3
|
|
|
Button('点击演示')
|
|
|
.onClick(()=>{
|
|
|
console.log('按钮被点击')
|
|
|
AlertDialog.show({
|
|
|
message: `${this.i}`
|
|
|
|
|
|
})
|
|
|
})
|
|
|
|
|
|
}
|
|
|
.width('100%')
|
|
|
|
|
|
}
|
|
|
.height('100%')
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这里`this.i = 3`报错,尚未解决
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 计数器案例
|
|
|
|
|
|
```
|
|
|
|
|
|
@Entry
|
|
|
@Component
|
|
|
|
|
|
|
|
|
struct Index {
|
|
|
@State i: number = 1
|
|
|
build() {
|
|
|
Row() {
|
|
|
Button('-')
|
|
|
.onClick(()=>{
|
|
|
this.i = this.i - 1
|
|
|
})
|
|
|
Text(`${this.i}`)
|
|
|
Button('+')
|
|
|
.onClick(()=>{
|
|
|
this.i = this.i + 1
|
|
|
})
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
##### 算数运算符和逻辑运算符
|
|
|
|
|
|
|
|
|
|
|
|
| 运算符名称 | 符号 |
|
|
|
| :--------: | :--: |
|
|
|
| 加 | + |
|
|
|
| 减 | - |
|
|
|
| 乘 | * |
|
|
|
| 除 | / |
|
|
|
| 取余 | % |
|
|
|
| 加法赋值 | += |
|
|
|
| 减法赋值 | -= |
|
|
|
| 乘法赋值 | *= |
|
|
|
| 除法赋值 | /= |
|
|
|
| 取余赋值 | %= |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 一元运算符
|
|
|
|
|
|
|
|
|
|
|
|
| 运算符名称 | 符号 |
|
|
|
| :--------: | :--: |
|
|
|
| 自加 | ++ |
|
|
|
| 自减 | -- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 比较运算符
|
|
|
|
|
|
==,>,<,<=,>=,!=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### 逻辑运算符
|
|
|
|
|
|
|| && !
|
|
|
|
|
|
|
|
|
|
|
|
##### 运算符优先级
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 数组
|
|
|
|
|
|
```
|
|
|
let songs: string[] = [···]
|
|
|
//数组长度
|
|
|
songs.length
|
|
|
//在开头加元素,返回操作后数组的长度
|
|
|
songs.unshift('内容1','内容2')
|
|
|
//在结尾加元素,返回操作后数组的长度
|
|
|
songs.push('内容1','内容2')
|
|
|
//从开头删除元素,返回删除的项
|
|
|
songs.shift()
|
|
|
//从结尾删除元素,返回删除的项
|
|
|
songs.pop()
|
|
|
//在任意位置添加/删除数组元素
|
|
|
songs.splice(操作开始的下标,删除的个数,新增的元素1,新增的元素2,···)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 语句结构
|
|
|
|
|
|
|
|
|
|
|
|
##### if else
|
|
|
|
|
|
##### switch
|
|
|
|
|
|
##### 三元条件表达式
|
|
|
|
|
|
```
|
|
|
let num1: number = 5
|
|
|
let num2: number = 10
|
|
|
//返回较大值
|
|
|
let res: number = num1 > num2 ? num1 : num2
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
表达式1 ? 表达式2 : 表达式3
|
|
|
|
|
|
表达式1为 true 返回表达式2,否则返回 表达式3
|
|
|
|
|
|
|
|
|
|
|
|
##### while
|
|
|
|
|
|
##### for
|
|
|
|
|
|
##### break && continue
|
|
|
|
|
|
|
|
|
|
|
|
##### 遍历数组 for...of
|
|
|
|
|
|
```
|
|
|
for(let item of names){
|
|
|
打印数组每一项item
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
##### 对象数组
|
|
|
|
|
|
```
|
|
|
//定义接口
|
|
|
interface Student {
|
|
|
Id: number
|
|
|
name: string
|
|
|
gender: string
|
|
|
age: number
|
|
|
}
|
|
|
|
|
|
let stuArr: Student[] = [
|
|
|
{Id: 1,name: '小米',gender: '男',age: 18},
|
|
|
{Id: 2,name: 'da米',gender: '男',age: 28}
|
|
|
]
|
|
|
//包括对象的复杂数据,可以通过一下方法打印到日志中
|
|
|
console.log('学生数组',JSON.stringify(stuArr))
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### ForEach-渲染控制
|
|
|
|
|
|
```
|
|
|
@State titles: string[] = ['1','2','3','4','5']
|
|
|
build() {
|
|
|
Column(){
|
|
|
ForEach(this.titles,(item: string,index) => {
|
|
|
Text(item)
|
|
|
.fontSize('24')
|
|
|
.fontWeight(700)
|
|
|
.fontColor(Color.Orange)
|
|
|
.width('100%')
|
|
|
.padding(15)
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 综合练习-生肖集卡片
|
|
|
|
|
|
|
|
|
|
|
|
#### 知识点引入
|
|
|
|
|
|
##### Badge角标
|
|
|
|
|
|
```
|
|
|
@Entry
|
|
|
@Component
|
|
|
struct Index {
|
|
|
build() {
|
|
|
Column(){
|
|
|
Badge({
|
|
|
count: 1,
|
|
|
position: BadgePosition.RightTop,
|
|
|
style: {
|
|
|
badgeSize: 20,
|
|
|
fontSize: 14,
|
|
|
badgeColor: '#FA2A2D'
|
|
|
}
|
|
|
}) {
|
|
|
Image($r('app.media.bg_01'))
|
|
|
.width(100)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##### Grid布局
|
|
|
|
|
|
方便快捷的布局规律的多排多列的相似的组件
|
|
|
|
|
|
```
|
|
|
Grid(){
|
|
|
ForEach([1,2,3,4,5,6,7,8,9,10,11,12],()=>{
|
|
|
GridItem(){
|
|
|
//GridItem 里有且只有一个子元素
|
|
|
Column(){
|
|
|
|
|
|
}
|
|
|
.width(80)
|
|
|
.height(80)
|
|
|
.backgroundColor(Color.Green)
|
|
|
.border({width: 1})
|
|
|
}
|
|
|
})
|
|
|
|
|
|
}
|
|
|
//设置在一行中,每一列占多少份宽度
|
|
|
.columnsTemplate('1fr 1fr 1fr')
|
|
|
//设置在一列中,每一行占多少份宽度
|
|
|
.rowsTemplate('1fr 1fr 1fr 1fr')
|
|
|
.width('100%')
|
|
|
.height(500)
|
|
|
.backgroundColor(Color.Pink)
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#####
|
|
|
|
|
|
## 抽卡源码
|
|
|
|
|
|
```tsx
|
|
|
interface ImageCount {
|
|
|
url: Resource;
|
|
|
count: number;
|
|
|
}
|
|
|
|
|
|
@Entry
|
|
|
@Component
|
|
|
struct Index {
|
|
|
@State images: ImageCount[] = [
|
|
|
{url: $r('app.media.bg_00'),count: 0},
|
|
|
{url: $r('app.media.bg_01'),count: 0},
|
|
|
{url: $r('app.media.bg_02'),count: 0},
|
|
|
{url: $r('app.media.bg_03'),count: 0},
|
|
|
{url: $r('app.media.bg_04'),count: 0},
|
|
|
{url: $r('app.media.bg_05'),count: 0},
|
|
|
];
|
|
|
//随机的抽卡序号
|
|
|
@State randomIndex: number = -1
|
|
|
//判断是否得到大奖
|
|
|
@State sum: number = 0
|
|
|
@State maskOpacity: number = 0
|
|
|
@State maskZIndex: number = -1
|
|
|
@State maskOpacity1: number = 0
|
|
|
@State maskZIndex1: 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(item.url)
|
|
|
.width(80)
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
.columnsTemplate('1fr 1fr 1fr')
|
|
|
.rowsTemplate('1fr 1fr')
|
|
|
.width('100%')
|
|
|
.height(300)
|
|
|
.backgroundColor(Color.Pink)
|
|
|
.margin({ top: 100 })
|
|
|
|
|
|
Button('立即抽卡')
|
|
|
.width(200)
|
|
|
.backgroundColor('#ed5b8c')
|
|
|
.margin({ top: 50 })
|
|
|
.onClick(()=>{
|
|
|
//点击达到跳转效果
|
|
|
this.maskOpacity = 1
|
|
|
this.maskZIndex = 99
|
|
|
//图片缩放
|
|
|
this.maskImgX = 1
|
|
|
this.maskImgY = 1
|
|
|
|
|
|
//计算随机数
|
|
|
this.randomIndex = Math.floor(Math.random() * 6)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
}
|
|
|
.width('100%')
|
|
|
.height('100%')
|
|
|
.backgroundColor(Color.Pink)
|
|
|
|
|
|
//抽卡遮罩层
|
|
|
Column({space: 30}) {
|
|
|
Text('获得生肖卡')
|
|
|
.fontColor('#f5ebcf')
|
|
|
.fontSize(25)
|
|
|
.fontWeight(FontWeight.Bold)
|
|
|
Image($r(`app.media.img_0${this.randomIndex}`))
|
|
|
.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 = 0
|
|
|
this.maskZIndex = -1
|
|
|
//重置图像缩放比为0
|
|
|
this.maskImgX = 0
|
|
|
this.maskImgY = 0
|
|
|
//开心收下后处理数据,需要更新页面。所以要更新整个对象
|
|
|
this.images[this.randomIndex] = {
|
|
|
url: $r(`app.media.img_0${this.randomIndex}`),
|
|
|
count: this.images[this.randomIndex].count + 1
|
|
|
}
|
|
|
if(this.images[this.randomIndex].count == 1)
|
|
|
{
|
|
|
this.sum ++
|
|
|
}
|
|
|
if(this.sum == 6)
|
|
|
{
|
|
|
this.maskOpacity1 = 1
|
|
|
this.maskZIndex1 = 99
|
|
|
}
|
|
|
|
|
|
|
|
|
})
|
|
|
}
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
.width('100%')
|
|
|
.height('100%')
|
|
|
.backgroundColor('#cc000000')
|
|
|
//设置透明度、层级
|
|
|
.opacity(this.maskOpacity)
|
|
|
.zIndex(this.maskZIndex)
|
|
|
//添加动画 animation
|
|
|
.animation({
|
|
|
duration: 200
|
|
|
})
|
|
|
|
|
|
//大奖遮罩层
|
|
|
Column(){
|
|
|
Text('恭喜获得大奖')
|
|
|
.fontColor('#f5ebcf')
|
|
|
.fontSize(25)
|
|
|
.fontWeight(700)
|
|
|
Image($r('app.media.xm'))
|
|
|
.width(300)
|
|
|
Button('再来一次')
|
|
|
.onClick(()=>{
|
|
|
|
|
|
})
|
|
|
.width(200)
|
|
|
.height(50)
|
|
|
.backgroundColor(Color.Transparent)
|
|
|
.border({width: 2,color: '#fff9e0'})
|
|
|
}
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
.width('100%')
|
|
|
.height('100%')
|
|
|
.backgroundColor('#cc000000')
|
|
|
.opacity(this.maskOpacity1)
|
|
|
.zIndex(this.maskZIndex1)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|