ToB企服应用市场:ToB评测及商务社交产业平台

标题: 鸿蒙开辟学习笔记2 [打印本页]

作者: 干翻全岛蛙蛙    时间: 2024-7-11 10:56
标题: 鸿蒙开辟学习笔记2
一、class 类

类是用于 创建对象模版。同时类声明也会引入一个 新范例,可界说其 实例属性方法构造函数
  1. // 类名 首字母大写(规范)
  2. class 类名 {
  3.         // 1、实例属性(字段)
  4.         // 2、构造函数
  5.         // 3、方法
  6. }
复制代码
1、属性(字段)

  1. class Person {
  2.         // 字段名: 类型 = 初始值
  3.         name: string = 'jack'       
  4.         // 可选字段可以不设置初始值
  5.         food?: string
  6. }
  7. const p: Person = new Person()
  8. console.log(p.name)
  9. // 可选字段在使用时需要配合 可选链操作符,避免出错
  10. // p.food?.length 表示:如果food存在,就取 length
  11. console.log(p.food?.length)
复制代码
2、构造函数 constructor

差别实例,将来必要有差别的字段初始值,必要通过构造函数来实现。
  1. /*
  2. class 类{
  3.         字段1:类型
  4.         字段2:类型
  5.         constructor(参数1...) {
  6.                 this.字段A = 参数1
  7.         }
  8. }
  9. const 实例1 = new 类(参数1...)
  10. */
  11. // 法1:构造函数接收一系列参数,所有参数都需要在 constructor 中列出来
  12. class Food {
  13.   name: string
  14.   price: number
  15.   constructor(name:string, price:number) {
  16.     this.name = name
  17.     this.price = price
  18.   }
  19. }
  20. let  f1: Food = new Food('西红柿', 6)
  21. console.log('f1 name:', f1.name)
  22. console.log('f1 price:', f1.price)
  23. // 法2:构造函数接收一个对象
  24. // 接口
  25. interface interfaceFood {
  26.   name: string
  27.   price: number
  28.   desc: string
  29. }
  30. class Food2 {
  31.   name: string
  32.   price: number
  33.   desc: string
  34.   constructor(paramsObj: interfaceFood) {
  35.     this.name = paramsObj.name
  36.     this.price = paramsObj.price
  37.     this.desc = paramsObj.desc
  38.   }
  39. }
  40. let f2 = new Food2({name: '土豆', price: 5, desc: '酸辣土豆丝'})
  41. console.log('name:',f2.name, 'price:', f2.price, 'desc:', f2.desc )
复制代码
3、界说方法

  1. /*class 类名{
  2.   方法名(参数...):返回值类型{
  3.     逻辑...
  4.     可以通过 this 获取实例对象
  5.   }
  6. }*/
  7. class Person {
  8.   name: string
  9.   constructor(name: string) {
  10.     this.name = name
  11.   }
  12.   sayHi(name):string {
  13.     console.log(`你好,${name},我是${this.name}`)
  14.     return `你好,${name},我是${this.name}`
  15.   }
  16. }
  17. let p: Person = new Person('张三')
  18. p.sayHi('李四')
复制代码
4、静态属性和方法

类可以添加属性、方法,后续访问必要通过 类 来完成,无法通过实例利用。
  1. /*class 类 {
  2.   static 字段: 类型
  3.   // 通常当作工具方法使用
  4.   static 方法() {}
  5. }
  6. 类.字段
  7. 类.方法()*/
  8. class Car {
  9.   static version: string = '1.9.0'
  10.   static getRandomNumber() {
  11.     return Math.random()
  12.   }
  13. }
复制代码
5、继承 extends 和 super 关键字

类可以通过 继承 快速获取别的一个类的 字段方法
  1. /*class 父类 {
  2.   // 字段
  3.   // 方法
  4.   // 构造函数
  5.   方法(){}
  6. }
  7. class 子类 extends 父类 {
  8.   // 自己的字段(属性)
  9.   // 自己的方法
  10.   // 可以重写父类方法
  11.   constructor() {
  12.     super()
  13.   }
  14.   方法() {
  15.     super.方法()// 调用父类方法
  16.   }
  17. }*/
  18. class Person {
  19.   name: string
  20.   constructor(name:string) {
  21.     this.name = name
  22.   }
  23.   sayHi() {
  24.     console.log(`你好,我叫${this.name}`)
  25.   }
  26. }
  27. class Student extends Person{
  28.   grade:string
  29.   // 子类中有额外的属性时,需要重写自己的构造函数
  30.   constructor(name:string, grade:string) {
  31.     // 子类的构造函数中,可以通过 super 去访问父类的属性和方法
  32.     // super() 父类构造函数、super.方法名(),super.属性名
  33.     // 使用 super() 调用父类的构造函数时,要将父类所需要的参数,依次传递过去
  34.     super(name)
  35.     // 完成自己属性的初始化
  36.     this.grade = grade
  37.   }
  38.   // 同名方法、属性的情况下,子类的优先级高于父类
  39.   sayHi():void {
  40.     super.sayHi()
  41.     console.log(`我是学生,今年${this.grade}`)
  42.   }
  43. }
  44. let s: Student = new Student('张三', '三年级')
  45. s.sayHi()
复制代码
6、instanceof

instanceof 运算符可以用来检测某个对象是否是某个类的实例。
  1. class Person {
  2. }
  3. class Student extends Person {
  4. }
  5. class Teacher extends Person {
  6. }
  7. let s: Student = new Student()
  8. console.log('s是否是Student的实例', s instanceof Student)        // true
  9. console.log('s是否是Person的实例', s instanceof Person)        // true
  10. console.log('s是否是Teacher的实例', s instanceof Teacher)        // true
复制代码
7、修饰符

类的方法和属性可以通过修饰符限制访问。
修饰符包括:readonly、private、protected、public。省略不写默以为 public。

  1. class Person {
  2.   // public 在程序的任何可访问该类的地方都是可见的(默认)
  3.   name: string
  4.   // readonly 只读,不可修改
  5.   readonly desc: string = '人类'
  6.   // private 私有,只能在 Person 类里面访问
  7.   private drink: string = '喝酒'
  8.   // protected 保护,在Person和Student中,都可以访问,其他地方不能访问
  9.   protected eat: string = '吃东西'
  10.   constructor(name) {
  11.     this.name = name
  12.     console.log(this.drink)
  13.   }
  14. }
  15. class Student extends Person {
  16.   constructor(name) {
  17.     super(name)
  18.     console.log(super.eat)
  19.   }
  20. }
复制代码
二、剩余参数和展开运算符

1、剩余参数

可以将函数或方法中一个不定数量的参数表示为一个数组。
  1. function sum(num1: number,num2: number,...argArr:number[]) {
  2.   let total = num1 + num2
  3.   for(let i of argArr) {
  4.     total += i
  5.   }
  6.   console.log('total', total)
  7. }
  8. sum(1,2)
  9. sum(1,2,3,4)
  10. sum(1,2,3,4,5,6)
复制代码
2、展开运算符

用于数组的平铺合并。(ArkTs 中,展开运算符只能用在数组上。)
  1. let arr1 = [1,2,3]
  2. let arr2 = [4,5,6]
  3. let arr3 = [...arr1, arr2]
  4. console.log('arr3', arr3)
复制代码
三、接口

1、继承 extends

  1. interface Animal {
  2.   name: string
  3.   age: number
  4. }
  5. interface Cat extends Animal {
  6.   hair: string
  7. }
  8. let c1: Cat = {
  9.   name: '布偶',
  10.   age: 2,
  11.   hair: '白色'
  12. }
复制代码
2、接口实现

接口实现:界说一个接口,约束 类 =》 类必要按照接口的要求,实现类的主体
  1. interface IDog {
  2.   name: string
  3.   age: number
  4.   eat: () => void
  5. }
  6. class Dog implements IDog {
  7.   name: string
  8.   age: number
  9.   constructor(name:string, age:number) {
  10.     this.name = name
  11.     this.age = age
  12.   }
  13.   eat: ()=> {
  14.   }
  15. }
复制代码
四、泛型

泛型可以让 函数 等,与多种 差别的范例 一起工作,灵活可复用。
通俗一点就是:范例是可变的。
1、泛型函数

  1. // 泛型函数:Type 是实际调用时,传过来的类型参数
  2. // 第一个 Type 是需要传递的参数,第二个Type是约束参数的类型,第三个Type是约束返回值的类型
  3. // function 函数名<Type>(形参:Type): Type {
  4. //   return 形参
  5. // }
  6. function f1<T>(arg:T): T {
  7.   return arg
  8. }
  9. console.log('str',f1<string>('abc'))
  10. // 会根据传参,进行类型推断,动态配置 T 类型参数的值
  11. console.log('arr',f1([1,2,3]))
  12. console.log('num',f1<number>(123))
复制代码
练习
  1. // 练习1:定义函数,参数是数组(数组值的类型不定),返回数组的长度
  2. function f2<T>(arg: T[]): number {
  3.   return arg.length
  4. }
  5. console.log('num',f2<number>([2,3,4]))
  6. console.log('str',f2(['2','3','4']))
  7. // 练习1:定义函数,参数是数组(数组值的类型不定),返回数组的最后一项
  8. function f3<T>(arg: T[]): T {
  9.   return arg[arg.length-1]
  10. }
  11. console.log('num',f3<number>([2,3,4]))
  12. console.log('str',f3(['a','b','c']))
复制代码
2、泛型约束

之前的范例参数,可以传递任何范例,没有限制。
如果盼望有限制 -》 泛型约束
  1. /*
  2. interface 接口 {
  3. }
  4. function 函数<Type extends 接口> {}
  5. */
  6. interface Ilength {
  7.   length: number
  8. }
  9. function fn<T extends Ilength>(params: T) {
  10.   console.log('',params.length);
  11. }
  12. fn<string>('123')
复制代码
3、多个泛型参数

  1. function func<T,T2>(param1: T, param2: T2) {
  2.   console.log('参数1',param1)
  3.   console.log('参数2',param2)
  4. }
  5. func<string, number[]>('abc', [123,22])
复制代码
4、泛型接口

界说接口的时候,团结泛型界说,就是泛型接口。
  1. /*interface 接口<Type> {
  2.   // 内部使用 Type
  3. }*/
  4. interface IdFunc<Type> {
  5.   id: (value:Type) => Type,
  6.   ids: () => Type[]
  7. }
  8. let obj: IdFunc<number> = {
  9.   id(value: number) {
  10.     return value
  11.   },
  12.   ids() {
  13.     return [1,2,3]
  14.   }
  15. }
  16. let obj2:IdFunc<string> = {
  17.   id(value:string) {
  18.     return value
  19.   },
  20.   ids() {
  21.     return ['1','2']
  22.   }
  23. }
复制代码
5、泛型类

界说类的时候,团结泛型界说,就是泛型类。
  1. class Person<T> {
  2.   id: T
  3.   constructor(id:T) {
  4.     this.id = id
  5.   }
  6.   getId() {
  7.     return this.id
  8.   }
  9. }
  10. // 使用
  11. let p = new Person<number>(13)
复制代码
五、模块化语法

模块化:把一个大的步伐,拆分为多少的小模块,通过特定的语法,可以进行恣意组合。
1、默认导出和导入

默认导出:指一个模块,只能默认导出 一个 对象。利用时,可以通过 as 自界说导出名称。
  1. // 导出
  2. export default XXX
  3. //导入
  4. import XXX from '模块路径'
  5. import XXX as YYY from '模块路径'
复制代码
2、按需导出和导入

按需导出:指一个模块,可以按照必要,导出多个特性。
  1. // modules.ets 导出
  2. let name: string = '张三'
  3. let age: number = 18
  4. let sayHello = () => {
  5.   console.log('你好')
  6. }
  7. export {name, age, sayHello}
  8. // index.ets导入
  9. import {name, age as myAge, sayHello} from '../tools/modules'
复制代码
3、全部导入

将所有的按需导入,全部导入进来。
  1. // modules.ets 导出
  2. let name: string = '张三'
  3. let age: number = 18
  4. let sayHello = () => {
  5.   console.log('你好')
  6. }
  7. export {name, age, sayHello}
  8. // index.ets导入
  9. import * as result from '../tools/modules'
  10. console.log('结果是:', result.name, result.age)
复制代码
六、自界说组件

由框架直接提高的称为体系组件,由开辟者界说的称为自界说组件。
语法:
  1. @Component
  2. struct 组件名 {
  3.   build() {
  4.   }
  5. }
复制代码
案例:
  1. @Component
  2. struct MyContent {
  3.   @State count: number = 0
  4.   build() {
  5.     Row() {
  6.       Text(this.count.toString()).fontSize(26)
  7.       Button('按钮')
  8.         .onClick(() => {
  9.           this.count ++
  10.         })
  11.     }
  12.       .width('100%')
  13.       .justifyContent(FlexAlign.Center)
  14.   }
  15. }
  16. @Entry
  17. @Component
  18. struct Index {
  19.   build() {
  20.     Column() {
  21.         MyContent()
  22.         MyContent()
  23.         MyContent()
  24.     }
  25.   }
  26. }
复制代码
1、通用属性和方法

自动移组件可以通过点语法,设置通用样式、通用变乱。
  1. // header.ets
  2. // 组件可以使用 @Preview 预览
  3. // @Preview
  4. @Component
  5. export struct Header {
  6.   build() {
  7.     Row() {
  8.       Text('头部')
  9.       Button('按钮')
  10.     }
  11.       .width(200)
  12.       .height(80)
  13.       .backgroundColor(Color.Pink)
  14.   }
  15. }
  16. // index.ets
  17. import { Header } from '../components/Header'
  18. @Entry
  19. @Component
  20. struct Index {
  21.   build() {
  22.     Column() {
  23.       Header()
  24.         .width(260)
  25.         .height(100)
  26.         .backgroundColor(Color.Gray)
  27.         .onClick(() => {
  28.           AlertDialog.show({
  29.             message: '点击了Header组件'
  30.           })
  31.         })
  32.     }
  33.   }
  34. }
复制代码
拓展:
组件可以作为一个模块,通过按需导入导出,大概默认导入导出利用。
2、成员变量和成员函数


  1. @Component
  2. struct MyPanel {
  3.   // 成员变量 - 可以外部传入覆盖,若需要状态管理,可以使用 @State
  4.   // 成员变量 - 数据
  5.   title: string = '我的订单'
  6.   extra: string = '全部订单'
  7.   @State count: number = 0
  8.   // 成员变量 - 函数
  9.   getMore = () => {
  10.     AlertDialog.show({
  11.       message: '获取更多'
  12.     })
  13.   }
  14.   // 成员函数 - 不可以外部传入覆盖
  15.   getContent() {
  16.     AlertDialog.show({
  17.       message: '查看内容'
  18.     })
  19.   }
  20.   build() {
  21.     Column() {
  22.       Row() {
  23.         Text(this.title)
  24.           .fontSize(20)
  25.         Text(this.extra)
  26.           .fontSize(20)
  27.           .onClick(() => {
  28.             this.getMore()
  29.           })
  30.       }
  31.         .width('100%')
  32.         .justifyContent(FlexAlign.SpaceBetween)
  33.       Column() {
  34.         Text(this.count.toString())
  35.         Button('按钮')
  36.           .onClick(() => {
  37.             this.count ++
  38.           })
  39.         Text('内容')
  40.           .fontSize(20)
  41.           .onClick(() => {
  42.             this.getContent()
  43.           })
  44.       }.padding(20)
  45.     }
  46.       .width('100%')
  47.       .height(200)
  48.       .padding(20)
  49.       .margin({bottom: 10})
  50.       .borderRadius(10)
  51.       .backgroundColor(Color.White)
  52.   }
  53. }
  54. @Entry
  55. @Component
  56. struct Index {
  57.   build() {
  58.     Column() {
  59.       MyPanel({
  60.         title: '我的订单',
  61.         extra: '全部订单 >',
  62.         count: 10,
  63.         getMore: () => {
  64.           AlertDialog.show({
  65.             message: '查看全部订单'
  66.           })
  67.         }
  68.       })
  69.       MyPanel({
  70.         title: '小米有品众筹',
  71.         extra: '7款众筹中 >',
  72.         count: 20,
  73.         getMore: () => {
  74.           AlertDialog.show({
  75.             message: '查看7款众筹'
  76.           })
  77.         }
  78.       })
  79.     }
  80.     .width('100%')
  81.     .height('100%')
  82.     .padding(20)
  83.     .backgroundColor('#ccc')
  84.   }
  85. }
复制代码
3、@BuilderParam 传递 UI

利用 @BuilderParam 构建函数,可以让自界说组件 允许外部传递 UI。(类似于 vue 中的插槽)
  1. @Component
  2. struct MyComp {
  3.   // 1、定义构建函数,接收外部传入的 ui,并设置默认值
  4.   @BuilderParam customerBuilder: () => void = this.defaultBuilder
  5.   @Builder defaultBuilder() {
  6.     Text('默认显示内容')
  7.   }
  8.   build() {
  9.     Column() {
  10.       // 2、使用 @BuilderParam 装饰的成员函数,构建函数,构建结构
  11.       this.customerBuilder()
  12.     }
  13.   }
  14. }
  15. @Entry
  16. @Component
  17. struct Index {
  18.   build() {
  19.     Column() {
  20.       MyComp(){
  21.       // 3、传入新的结构
  22.         Button('传入的显示内容')
  23.       }
  24.     }
  25.   }
  26. }
复制代码
4、多个 @BuilderParam

子组件有多个 BuilderParam,必须通过参数的方式传入。
  1. @Component
  2. struct MyCard {
  3.   @BuilderParam hBuilder: () => void = this.hDefaultBuilder
  4.   @BuilderParam cBuilder: () => void = this.cDefaultBuilder
  5.   @Builder hDefaultBuilder() {
  6.     Text('默认标题部分')
  7.   }
  8.   @Builder cDefaultBuilder() {
  9.     Text('默认内容部分')
  10.   }
  11.   build() {
  12.     Column() {
  13.       Row() {
  14.         this.hBuilder()
  15.       }
  16.       .width('100%')
  17.       .padding(10)
  18.       .border({width:{bottom:1},color:'#999'})
  19.       Row() {
  20.         this.cBuilder()
  21.       }
  22.       .height(80)
  23.       .width('100%')
  24.       .padding(10)
  25.     }
  26.     .borderRadius(6)
  27.     .backgroundColor(Color.White)
  28.   }
  29. }
  30. @Entry
  31. @Component
  32. struct Index {
  33.   @Builder pHBuilder() {
  34.     Text('父组件传递的标题')
  35.   }
  36.   @Builder pCBuilder() {
  37.     Text('父组件传递的内容')
  38.   }
  39.   build() {
  40.     Column({space:10}) {
  41.       MyCard({
  42.         hBuilder: this.pHBuilder,
  43.         cBuilder: this.pCBuilder
  44.       })
  45.       MyCard()
  46.     }
  47.     .width('100%')
  48.     .height('100%')
  49.     .padding(20)
  50.     .backgroundColor('#ccc')
  51.   }
  52. }
复制代码
七、状态管理-@state增补

状态管理:当运行时的状态变量变化,带来 UI 的重新渲染,在 ArkUI 中统称为 状态管理机制
变量必须被装饰器@state修饰才气称为状态变量。

  1. interface Car {
  2.   name: string
  3. }
  4. interface Person {
  5.   name: string
  6.   car: Car
  7. }
  8. @Entry
  9. @Component
  10. struct Index {
  11.   @State message:string = '你好'
  12.   @State p: Person = {
  13.     name: '张三',
  14.     car: {
  15.       name: '奥迪'
  16.     }
  17.   }
  18.   build() {
  19.     Column({space:10}) {
  20.       Text(this.message)
  21.       Button('修改message')
  22.         .onClick(() => {
  23.           this.message = '修改了message'
  24.         })
  25.       Text(JSON.stringify(this.p))
  26.       Button('修改 obj 的name')
  27.         .onClick(() => {
  28.           this.p.name = '李四'
  29.         })
  30.       Button('修改 obj.car 的name')
  31.         .onClick(() => {
  32.           // 直接修改嵌套对象的属性,状态不会被检测到,页面ui不会更新
  33.           // this.p.car.name = '保时捷'
  34.           // 嵌套对象重新赋值,可以进行状态检测
  35.           this.p.car = {
  36.             name: '保时捷'
  37.           }
  38.           console.log(this.p.car.name)
  39.         })
  40.     }
  41.     .width('100%')
  42.     .height('100%')
  43.     .padding(20)
  44.     .backgroundColor('#ccc')
  45.   }
  46. }
复制代码
八、@Prop 父向子单向传值

@Prop装饰的变量可以和父组件创建单向的同步关系。
@Prop装饰的变量时可变的,但是变化不会同步回其父组件,子组件若要更新父组件的数据,可通过成员变量,从父组件传递一个方法给子组件。
  1. @Component
  2. struct Son {
  3.   @Prop sCar:string = ''
  4.   changeCar = (newCar:string) => {}
  5.   build() {
  6.     Column() {
  7.       Text(`子组件--${this.sCar}`)
  8.       Button('换车')
  9.         .onClick(() => {
  10.           this.changeCar('宝马')
  11.         })
  12.     }
  13.       .width(200)
  14.       .height(100)
  15.       .backgroundColor(Color.Pink)
  16.   }
  17. }
  18. @Entry
  19. @Component
  20. struct Index {
  21.   @State car:string = '奔驰'
  22.   build() {
  23.     Column({space:10}) {
  24.       Text(`父组件--${this.car}`)
  25.       Button('换车').onClick(() => {
  26.         this.car = this.car === '奔驰'? '保时捷' : '奔驰'
  27.       })
  28.       Son({
  29.         sCar: this.car,
  30.         changeCar: (newCar:string) => {
  31.           this.car = newCar
  32.         }
  33.       })
  34.     }
  35.     .padding(50)
  36.     .backgroundColor('#ccc')
  37.   }
  38. }
复制代码
九、@Link 双向同步

子组件通过 @Link 修饰的变量,在子组件内部修改,回同步到父组件中。
  1. @Component
  2. struct sonComp {
  3.   @Link count:number
  4.   @Link person: Person
  5.   build() {
  6.     Column() {
  7.       Text('子组件').fontSize(30)
  8.       Text(this.count.toString()).fontSize(28)
  9.       Text(JSON.stringify(this.person)).fontSize(28)
  10.       Button('修改数据').fontSize(24).margin({top:10})
  11.         .onClick(() => {
  12.           this.count --
  13.           this.person.name = 'ls'
  14.         })
  15.     }
  16.     .width(300)
  17.     .height(200)
  18.     .justifyContent(FlexAlign.Center)
  19.     .margin({top: 60})
  20.     .borderRadius(10)
  21.     .backgroundColor('#acc4a0')
  22.   }
  23. }
  24. interface Person {
  25.   name: string
  26.   age: number
  27. }
  28. @Entry
  29. @Component
  30. struct Index {
  31.   @State count:number = 0
  32.   @State person:Person = {
  33.     name: 'zs',
  34.     age: 18
  35.   }
  36.   build() {
  37.     Column() {
  38.       Text('父组件').fontSize(30)
  39.       Text(this.count.toString()).fontSize(28)
  40.       Text(JSON.stringify(this.person)).fontSize(28)
  41.       Button('修改数据').fontSize(28)
  42.         .onClick(() => {
  43.           this.count ++
  44.           this.person.name = 'ww'
  45.         })
  46.       sonComp({
  47.         count: this.count,
  48.         person: this.person
  49.       })
  50.     }
  51.     .width('100%')
  52.     .height('100%')
  53.     .padding({top: 60})
  54.     .backgroundColor('#ddd')
  55.   }
  56. }
复制代码
十、@Provide 和 @Consume 祖孙级组件传值

将数据传递给后代,和后代的数据进行双向数据绑定。
步调:
1、将父组件的状态属性利用@Provide修饰
2、后代组件将必要的属性通过@Consume修饰
  1. interface Person {
  2.   name: string
  3.   age: number
  4. }
  5. @Entry
  6. @Component
  7. struct RootComp {
  8.   @Provide count:number = 20
  9.   @Provide person:Person = {
  10.     name: 'aaa',
  11.     age: 18
  12.   }
  13.   build() {
  14.     Column() {
  15.       Text('根组件').fontSize(30)
  16.       Text(this.count.toString()).fontSize(28)
  17.       Text(JSON.stringify(this.person)).fontSize(30)
  18.       Button('修改数据').fontSize(28).onClick(() => {
  19.         this.count ++
  20.         this.person.name = 'bbb'
  21.       })
  22.       parentComp()
  23.     }
  24.     .width('100%')
  25.     .height('100%')
  26.     .padding({top: 60})
  27.     .backgroundColor('#ddd')
  28.   }
  29. }
  30. @Component
  31. struct parentComp {
  32.   build() {
  33.     Column() {
  34.       Text('父组件').fontSize(30)
  35.       sonComp()
  36.     }
  37.     .width('100%')
  38.     .height(500)
  39.     .backgroundColor('#999')
  40.     // sonComp()
  41.   }
  42. }
  43. @Component
  44. struct sonComp {
  45.   @Consume count:number
  46.   @Consume person:Person
  47.   build() {
  48.     Column() {
  49.       Text('子组件').fontSize(30)
  50.       Text(this.count.toString()).fontSize(30)
  51.       Text(JSON.stringify(this.person)).fontSize(30)
  52.       Button('修改数据').fontSize(28).onClick(() => {
  53.         this.count --
  54.         this.person.name = 'ccc'
  55.       })
  56.     }
  57.     .width(300)
  58.     .height(200)
  59.     .justifyContent(FlexAlign.Center)
  60.     .margin({top: 60})
  61.     .borderRadius(10)
  62.     .backgroundColor('#acc4a0')
  63.   }
  64. }
复制代码
十一、@Observed 和 @ObjectLink 嵌套对象数组属性变化

阐明:装饰器仅能观察到 第一层 的变化,对于多层嵌套的环境,好比数组对象等,他们的第二层属性变化是无法观察到的,这就引出了 @Observed 和 @ObjectLink 装饰器。
作用:用于在涉及嵌套对象或数组的场景中进行双向数据同步。
属性更新的逻辑:当 @Observed 装饰过的数据,属性改变时,就会监听到遍历依赖它的 @ObjectLink 包装类,通知数据更新
注意:@ObjectLink 修饰符不能用在 Entry 修饰的组件中,可以将 Entry 中对应部分,拆分为一个子组件。
  1. interface IPerson {
  2.   name: string
  3.   age: number
  4. }
  5. @Observed
  6. class Person {
  7.   name: string
  8.   age: number
  9.   constructor(obj: IPerson) {
  10.     this.name = obj.name
  11.     this.age = obj.age
  12.   }
  13. }
  14. @Entry
  15. @Component
  16. struct RootComp {
  17.   @State persons: Person[] = [
  18.     new Person({ name: '张三', age: 18 }),
  19.     new Person({ name: '李四', age: 18 }),
  20.     new Person({ name: '王五', age: 18 })
  21.   ]
  22.   build() {
  23.     Column() {
  24.       ForEach(this.persons, (item: Person, index: number) => {
  25.         itemComp({
  26.           item: item,
  27.           addAge: () => {
  28.             item.age ++
  29.             // this.persons.splice(index, 1, item)
  30.           }
  31.         })
  32.       })
  33.     }
  34.     .width('100%')
  35.     .height('100%')
  36.     .padding({top: 30,left: 10, right: 10})
  37.     .backgroundColor('#ddd')
  38.   }
  39. }
  40. @Component
  41. struct itemComp {
  42.   // 属性更新的逻辑:当 @Observed 装饰过的数据,属性改变时,
  43.   // 就会监听到遍历依赖它的 @ObjectLink 包装类,通知数据更新
  44.   // 注意:entry 组件无法直接使用 @ObjectLink ,需要包一层
  45.   @ObjectLink item: Person
  46.   addAge = () => {}
  47.   build() {
  48.     Column() {
  49.       Row(){
  50.         Row() {
  51.           Text(`姓名:${this.item.name}`).fontSize(20)
  52.           Text(`年龄:${this.item.age}`).fontSize(20)
  53.         }
  54.         Button('修改数据').fontSize(18)
  55.           .onClick(() => {
  56.             // this.addAge()
  57.             this.item.age ++
  58.           })
  59.       }
  60.       .width('100%')
  61.       .height(100)
  62.       .padding({left: 10, right: 10})
  63.       .justifyContent(FlexAlign.SpaceBetween)
  64.       .margin({bottom: 10})
  65.       .borderRadius(10)
  66.       .backgroundColor('#eee')
  67.     }
  68.   }
  69. }
复制代码
十二、新建页面、路由跳转

1、新建页面


2、页面跳转和退却

  1. router.pushUrl({
  2.    url: "pages/Index"
  3. })
复制代码
  1. router.replaceUrl({
  2.   url: "pages/Index"
  3. })
复制代码
  1. router.back()
复制代码
3、页面栈

页面栈是用来存储步伐运行时页面的一种 数据结构,遵照先辈先出的原则。
页面栈的最大容量为 32 个页面

4、路由模式

路由提供了两种差别的跳转模式:
  1. router.pushUrl({
  2.   url: "pages/Index"
  3. }, router.RouterMode.Single)
  4. router.pushUrl({
  5.   url: "pages/Index"
  6. }, router.RouterMode.Standard)
复制代码
5、路由传参

  1. router.pushUrl({
  2.   url: 'pages/Details',
  3.   params: {
  4.     msg: '测试信息',
  5.     name: this.name
  6.   }
  7. })
复制代码
  1. aboutToAppear() {
  2.     // as 为类型断言,这里要把获取到的路由参数转为具体的类型,否则无法通过点语法获取值
  3.     let info = router.getParams() as Info
  4.     console.log(info.name)
  5.   }
复制代码
十二、生命周期


页面嵌套组件时,生命周期钩子执行顺序为:
父 aboutToAppear -》子 aboutToAppear -》父 onPageShow -》父 aboutToDisappear -》子 aboutToDisappear
十三、Stage 模型



1)

AppScope/app.json5:设置应用信息,对应的图片放在 AppScope/resources/base/media 目录下。
AppScope/resources/base/element/string.json:设置设置-》应用-》app 的描述信息
好像json5中设置的信息是在对应目录下的 string.json 中,对应的资源在对应 media 目录中。

2)

src/main/resources/base/element/string.json:设置变量的key和value,在 module.json5 中通过"$string:module_desc"($string是指 string.json 文件, 背面是指name为module_desc对应的value值)取值设置对应信息。
src/main/module.json5:abilities 设置显示信息,包括在桌面的图标和名称等。对应的图片等资源放在src/main/resources/base/media目录下。

3)UIAbility

好像就是手机上运行的 app 任务,单 UIAbility 就是一个 app 只能运行 1 个任务,多 UIAbility 就是1个 app 可以运行多个任务,好比 微信和微信小步伐


1. 同模块新建其他 ability


2.差别模块新建其他 ability


3. 同模块 Ability 拉起

从一个 Ability 中唤起另一个 Ability(同模块)
1、准备 want 作为 UIAbility 的启动参数
2、利用上下文对象 context,调用 startAbility 传入 want 启动
  1. import Want from '@ohos.app.ability.Want'
  2. import common from '@ohos.app.ability.common'
  3. @Entry
  4. @Component
  5. struct Index {
  6.   // 从一个 Ability 中唤起另一个 Ability(同模块)
  7.   // 1、准备 want 作为 UIAbility 的启动参数
  8.   // 2、利用上下文对象 context,调用 startAbility 传入 want 启动
  9.   // 获取上下文对象
  10.   context = getContext(this) as common.UIAbilityContext
  11.   build() {
  12.     Column() {
  13.       Text('entryability----Index').fontSize(30).fontWeight(FontWeight.Bold)
  14.       Button('唤起功能').onClick(() => {
  15.         // 1、准备 want (参数信息)
  16.         let wantInfo: Want = {
  17.           deviceId: '', //  空表示本设备
  18.           bundleName: 'com.example.myapplication', // AppScope/app.json5 中的 bundleName
  19.           moduleName: 'entry', // 模块名
  20.           abilityName: 'TwoAbility1', // src/main/module.json5 中的对应的 abilitie name
  21.           parameters: {
  22.             info: '来自 entryability'
  23.           }
  24.         }
  25.         // 2、利用 context startAbility 调起 UIAbility
  26.         this.context.startAbility(wantInfo)
  27.       })
  28.     }
  29.   }
  30. }
复制代码
4. 差别模块拉起

跟 3. 同模块 Ability 拉起 方法一样,只是必要修改 wantInfo 中的 moduleName、abilityName
  1. Button('唤起不同模块的 abilitie 功能').onClick(() => {
  2.   // 1、准备 want (参数信息)
  3.   let wantInfo: Want = {
  4.     deviceId: '', //  空表示本设备
  5.     bundleName: 'com.example.myapplication', // AppScope/app.json5 中的 bundleName
  6.     moduleName: 'TestModule', // 模块名
  7.     abilityName: 'TestModuleAbility', // src/main/module.json5 中的对应的 abilitie name
  8.     parameters: {
  9.       info: '来自 TestModuleAbility'
  10.     }
  11.   }
  12.   // 2、利用 context startAbility 调起 UIAbility
  13.   this.context.startAbility(wantInfo)
  14. })
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4