main
LeJingS 6 months ago
commit 644d74ea51

@ -0,0 +1,429 @@
### 常用组件
##### 切换按钮
```tsx
ToggleType.Switch 开关
ToggleType.Checkbox 复选框
ToggleType.Button 按钮
```
##### 文本输入
```
TextInput
```
##### 进度条
```
Progress
```
##### 弹窗
```
import promptAction form '@ohos.promptAction'
showToast()
```
##### 警告对话框
```
AlertDialog
```
##### 操作列表弹窗
```
ActionSheet
```
##### 选择器弹窗
```
TextPickerDialog文本选择器
DatePickerDialog日期选择器
TimePickerDialog时间选择器
```
##### 自定义弹窗
```
```
### 样式复用
## 状态管理
#### @State
```鸿蒙
@Entry
@Component
struct Index{
@State count: number = 1;
build() {
Column({space: 50}){
Row({space: 10}){
Text('@State')
Counter(){
Text(this.count.toString())
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
.width('100%')
.backgroundColor('#CCE3CB')
.padding(10)
.borderRadius(20)
.justifyContent(FlexAlign.Center)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.White)
.padding(10)
}
}
```
#### @Prop
父组件的变化可以同步到子组件,反之不可
Prop装饰的变量不允许本地初始化只能通过父组件向子组件传参进行初始化
```
@Entry
@Component
struct Parent {
@State count: number = 1;
build() {
Column() {
Column({ space: 10 }) {
//父组件标题
Text('父组件').textStyle()
//父组件计数器
Row({ space: 10 }) {
Text('@State').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
//子组件
Child({ count: this.count })
}
.containerStyle('#EFEFEF')
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.White)
.padding(10)
}
}
@Component
struct Child {
@Prop count: number ;
build() {
Column({ space: 10 }) {
//子组件标题
Text('子组件').textStyle()
//子组件计数器
Row({ space: 10 }) {
Text('@Prop').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
}
.containerStyle("#CCE3CB")
}
}
@Extend(Text) function textStyle() {
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
@Extend(Column) function containerStyle(color: ResourceColor) {
.width('100%')
.backgroundColor(color)
.padding(10)
.borderRadius(20)
}
```
父变子同步,子变父不变
#### @Link
父子双向同步
变量不允许本地初始化,只能通过父组件向子组件传参进行初始化
```
@Entry
@Component
struct Parent {
@State count: number = 1;
build() {
Column() {
Column({ space: 10 }) {
//父组件标题
Text('父组件').textStyle()
//父组件计数器
Row({ space: 10 }) {
Text('@State').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
//子组件
Child({ count: $count })
}
.containerStyle(Color.White)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor('#EFEFEF')
.padding(10)
}
}
@Component
struct Child {
@Link count: number;
build() {
Column({ space: 10 }) {
//子组件标题
Text('子组件').textStyle()
//子组件计数器
Row({ space: 10 }) {
Text('@Link').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
}
.containerStyle('#CCE3CB')
}
}
@Extend(Text) function textStyle() {
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
@Extend(Column) function containerStyle(color: ResourceColor) {
.width('100%')
.backgroundColor(color)
.padding(10)
.borderRadius(20)
}
```
#### @Provide & @Consume
用于跨组件层级传递状态信息
@Provide 装饰祖先,必须进行本地初始化
@Consume 装饰后代,不允许本地初始化,通过相同变量名绑定
双向同步
```
@Entry
@Component
struct GrandParent {
@Provide count: number = 1;
build() {
Column() {
Column({ space: 10 }) {
//祖先组件标题
Text('祖先组件').textStyle()
//祖先组件计数器
Row({ space: 10 }) {
Text('@Provide').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
//父组件
Parent()
}
.containerStyle(Color.White)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor('#EFEFEF')
.padding(10)
}
}
@Component
struct Parent {
build() {
Column({ space: 10 }) {
//父组件标题
Text('父组件').textStyle()
//子组件
Child()
}
.containerStyle('#CCE3CB')
}
}
@Component
export struct Child {
@Consume count: number;
build() {
Column({ space: 10 }) {
//子组件标题
Text('子组件').textStyle()
//子组件计数器
Row({ space: 10 }) {
Text('@Consume').textStyle()
Counter() {
Text(this.count.toString()).textStyle()
}
.onInc(() => this.count++)
.onDec(() => this.count--)
}
}
.containerStyle('#f6c867')
}
}
@Extend(Text) function textStyle() {
.fontSize(25)
.fontWeight(FontWeight.Bold)
}
@Extend(Column) function containerStyle(color: ResourceColor) {
.width('100%')
.backgroundColor(color)
.padding(10)
.borderRadius(20)
}
```

@ -0,0 +1,147 @@
# 基础语法
### 基础数据类型的定义
```tsx
//字符串类型
let title: string = '急急急'
//number
let age: number = 18
//boolean
let isLogin: boolean = true
//常量
const PI: number = 3.1415926
```
### 数组
```tsx
let names: string[] = ['jack','li','wang']
```
### 函数
```tsx
function 函数名(形参:类型){
函数体
return
}
//箭头函数
let 函数名 = () =>{
//函数体
}
```
### 对象
```tsx
//定义对象并使用
//1. 定义接口
interface Person{
name: string
age: number
weight: number
dance: (i: number) =>{
console.log('ming跳了',i,'次舞')
}
}
//基于接口,定义对象
let ym: Person = {
name: 'ming',
age: 18,
weight: 90
}
//获取对象属性值 对象名.属性名
console.log('体重:',ym.weight)
```
### 联合类型
```tsx
let judge: number|string = 100
judge = 'A'
```
### 枚举
```tex
//约定变量只能在一组数据范围中选择值
enum ThemeColor{
Red = '#ffof29'
Orange = '#ff7100'
Green = '#30b30e'
}
//引用后color只能在ThemeColor中取值
let color: ThemeColor = ThemeColor.Red
```

@ -0,0 +1,457 @@
# 界面开发
#### 开发布局思路
开发的最小单位是组件
基础组件:内容
容器组件:布局排版
```tsx
build(){
Column(){
Text('简介')
Row(){
Text('The one')
Text('The two')
Text('The there')
Text('The fore')
}
}
}
```
### 组件的属性方法
用于调整组件属性,美化外观,优化样式
```tsx
//
Text('简介')
.height(40)
.fontSize(20)
...
```
##### 颜色设置
```
//设置颜色
.fontColor(颜色值)
枚举颜色Color.颜色名
#开头的16进制颜色
```
##### 文字溢出显示省略号、行高
```tsx
Text('')
.textOverflow({
overflow: TextOverflow.Ellipsis
})
.maxLines(2)
//行高
.lineHeight(数字)
```
##### Image
```tsx
//网图加载
Image('图片网络链接')
//本地地址
Image($r('本地地址'))
//一般在 ./resources/base/medio/
Image($r('app.medio.图片名称'))
```
##### 输入框与按钮
```tsx
//同一容器中间隙space
Column({space: 15}){
TextInput({
placeholder: '请输入用户名'
})
TextInput({
placeholder: '请输入密码'
}).type(InputType.Password)
Button('登录')
.width(200)
}
```
##### 居中
```tsx
Column(){
}
.width('100%')
```
##### svg图标矢量图
特点:任意缩放大小不失真,可以改颜色
```tsx
Image($r(''))
.fillColor(Color.Orange)
```
### 布局元素的组成
- 内边距
- 外边距
- 边框
- 内容区域
##### 内边距 padding
```
//总体设置
Text('内边距padding')
.padding(20)
//分别设置
Text('内边距padding')
.padding({
top: 10,
right: 20,
bottom: 40,
left: 80
})
```
##### 外边距 margin
```
Text('外边距margin')
.margin(20)
//分别设置同上
```
##### 边框 border
```
.border({
width: 1,
color: Color.Red
style: BorderStyle.Dashed
})
//单边框,示例左边框。同理,颜色和样式也可以单独配置
.border({
width: {
left: 1
}
})
```
##### 设置组件圆角
```
Text('内边距padding')
.borderRadius(5)
.backgroundColor(Color.Blue)
```
##### 特殊圆角
- 正圆
```
Text('正圆')
.width(100)
.height(100)
.borderRadius(50)
```
- 胶囊按钮
```
Text('正圆')
.width(50)
.height(50)
.borderRadius(25)
```
### 背景
##### 背景图片基本引入
```tsx
Text('内容文本')
.width(200)
.height(100)
.backgroundColor(Color.Green)
.backgroundImage($r('app.media.cat'))
```
##### 背景图片平铺
```
Text('内容文本')
.width(200)
.height(100)
.backgroundColor(Color.Green)
.backgroundImage($r('app.media.cat'),ImageRepeat.XY)
```
##### 背景图片位置设置
```
Text('内容文本')
.width(200)
.height(100)
.backgroundColor(Color.Pink)
.backgroundImage($r('app.media.cat'))
//.backgroundImagePosition({x: 50,y: 10})
.backgroundImagePosition(Alignment.Center)
```
注意:背景定位默认单位为 px 实际的物理像素点 对于不同设备显示会有不同
宽高默认单位 vp 虚拟像素,可以自动转换
转换方法:
```
vp2px(数值)
```
##### 背景尺寸大小设置
```
Text('内容文本')
.width(200)
.height(100)
.backgroundColor(Color.Pink)
.backgroundImage($r('app.media.cat'))
.backgroundImageSize(ImageSize.Cover)
```
### 线性布局
Column & Row
##### 主轴对齐方式
```
Column({space: 15}){
Text()
.width(200).height(100)
.backgroundColor(Color.Pink)
.border({width: 2})
Text()
.width(200).height(100)
.backgroundColor(Color.Pink)
.border({width: 2})
.margin(5)
Text()
.width(200).height(100)
.backgroundColor(Color.Pink)
.border({width: 2})
}
.width('100%')
.height('100%')
.backgroundColor('#ccc')
.justifyContent(FlexAlign.SpaceEvenly)
```
##### 交叉轴对齐方式
```
//对于Column
.alignItems(HorizontalAlign.Start)
//对于Row
.alignItems(VerticalAlign.Top)
```
##### 自适应伸缩
```
.layoutWeight(权重)
```
### 弹性布局Flex
Flex默认主轴水平往右交叉轴垂直向下
```
//设置主轴方向、对齐方式、交叉轴对齐方式、布局换行(单行布局还是多行布局)
Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.SpaceAround,
alignItems: ItemAlign.Stretch
wrap: FlexWrap.Wrap
}){
}
```
### 绝对定位
优势是灵活
参照父组件的左上角进行偏移
```
Text('')
.position({
x: 0,
y: 0
})
```
调整组件层级
```
.zIndex(数字)
```
### 层叠布局
```
Stack(){
Text(){
.zIndex(3)
}
Text(){
.zIndex(4)
}
Text(){
.zIndex(5)
}
}
```

@ -0,0 +1,546 @@
# 构建应用
##### 字符串拼接
```
//直接用+号拼接
'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)
}
}
}
```

@ -0,0 +1,109 @@
# 组件化开发
### 轮播组件Swiper
Swiper是一个容器组件当设置了多个子组件后可以对这些子组件进行轮播显示
```
Swiper(){
//轮播内容
}
.width()
.height()
//会自动拉伸轮播内容的大小
Column(){
Swiper(){
Text('1')
.backgroundColor(Color.Blue)
Text('2')
.backgroundColor(Color.Green)
Text('3')
.backgroundColor(Color.Orange)
}
.width('100%')
.height(100)
}
```
##### Swiper常见属性
| 属性 | 传值 | 作用 | 默认值 |
| :------: | :-----: | :-------------------: | :----: |
| loop | boolean | 是否开启循环 | true |
| autoPlay | boolean | 是否自动播放 | false |
| interval | number | 自动播放时间间隔ms) | 3000 |
| vertical | boolean | 纵向滑动轮播 | false |
##### Swiper指示器设置
```tsx
.indicator(
Indicator.dot()//小圆点
.itemWidth(10)//默认宽高,颜色
//.itemHeight(20)
//.color(Color.Black)
.selectedItemWidth(30)//选中宽高,颜色
//.selectedItemHeight(30)
.selectedColor(Color.White)
)
```
### 样式&结构重用
##### @Extend 扩展组件(样式、事件)
1. 全局
2. 要求统一组件
3. 格式:
```
@Extend(Text)//应用到哪一类组件
function text1(color: ResourceColor,txt: string)//传递参数
{
//组件样式设置
}
```
##### @Styles 抽取通用属性、事件
1. 允许不同类型组件之间样式复用
##### @Builder 自定义构建函数(结构、样式、事件)

@ -0,0 +1,6 @@
视频教程参考:
【全网首发黑马程序员鸿蒙 HarmonyOS NEXT星河版零基础入门到实战零基础也能快速入门鸿蒙开发教程】
https://www.bilibili.com/video/BV14t421W7pA?p=2&vd_source=29d4037073f64a57cf6669b9b5c3021c
Loading…
Cancel
Save