王学岗鸿蒙开发(北向)——————(七、八)ArkUi的各种装饰器

arts包含如下:1,装饰器 ;2,组件的描述(build函数);3,自定义组件(@Component修饰的),是可复用的单元;4,系统的组件(鸿蒙官方提供);等
装饰器的作用:装饰类、变量、方法、结构等。
@State 可以用数据驱动UI更新。
@Entry 入口文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组件的调用

@Entry
@Component
@Preview
struct Index {
  @State message: string = 'Hello World'

  aboutToAppear() {

  }

  build() {
    Column() {
      //可以不传参
      Test()
      //也可以传参,使用{}
      Test({msg:'马超'})

    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }

  aboutToDisappear() {

  }
}
//自定义组件
@Component
struct Test{
  private msg:string = '赵云';
  build(){
    Column(){
      Text(this.msg)
    }
  }
}

在这里插入图片描述

@Entry
@Component
@Preview
struct Index {
  @State message: string = 'Hello World'
   msg:string = '曹操'
  aboutToAppear() {

  }

  build() {
    Column() {
      //调用的时候需要使用this.this指代当前所属组件
      //注意,这里传递的是值不是引用。如果在Button的点击方法中更改了
      //this.msg的值,MyBuilderFunction1不会修改显示内容
      this.MyBuilderFunction1(this.msg)
      this.MyBuilderFunction2()
      this.MyBuilderFunction3()
      //调用全局构建函数,不能使用this
      GlobalBuilder()
      Button('按钮').onClick((event:ClickEvent)=>{
        console.log("点击了按钮")
        this.msg = '曹丕'})
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }

  aboutToDisappear() {

  }

  @Builder //自定义组件内构建函数
  MyBuilderFunction0() {
    Text(this.message).fontSize(50)
  }

  @Builder //自定义组件内构建函数
  MyBuilderFunction1(msg:string) {
    Text(msg).fontSize(50)
  }

  @Builder //自定义组件内构建函数
  MyBuilderFunction2() {
    Text('刘备').fontSize(50)
  }

  @Builder //自定义组件内构建函数
  MyBuilderFunction3() {
    Text('孙坚').fontSize(50)
  }

}

//全局构建函数,需要使用function
@Builder
function GlobalBuilder(){

  Text('我是全局的构建函数').fontSize(40)
}
@Entry
@Component
@Preview
struct Index {
  @State message: string = 'Hello World'
   msg:string = '曹操'
  aboutToAppear() {

  }

  build() {
    Column() {
      //MyBuilderFunction后这里不能用括号
     Child({builder:this.MyBuilderFunction})
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }

  aboutToDisappear() {

  }
  @Builder
  MyBuilderFunction(){
    Text('我爱你爱你').fontSize(50)
  }
}
//子组件被父组件调用,
@Component
struct Child{
  //不初始化会报错
  //Property 'builder' in the custom component 'Child' is missing assignment or initialization.
 // @BuilderParam装饰器:引用@Builder函数
  //  当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。
  //  若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。
  //  为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,
  //  开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,
  //  类似slot占位符。

  @BuilderParam builder:()=>void;
  build(){
    Column(){
      this.builder()
      Text('吕玲绮').fontSize(50)
    }
  }
}

在这里插入图片描述

@Entry
@Component
@Preview
struct Index {
  @State message: string = 'Hello World'
  msg: string = '曹操'

  aboutToAppear() {

  }

  build() {
    Column() {
    //如果名字相同,都叫MyStyle,组件内的优先级高
    //@Styles不能传递参数
      Text('曹操').MyStyle1()
      Text('刘备').MyStyle2()
      Text('孙权').MyStyle1()
      Text('吕布').MyStyle2()
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
  //自定义样式,组件内不需要function,只能是通用属性和事件,
  @Styles
  MyStyle1(){
    .width('100%')
    .height(100)
    .backgroundColor('green')
  }
}
//自定义样式,组件外需要function,只能是通用样式,不能传递参数
@Styles
function MyStyle2(){
  .width('100%')
  .height(100)
  .backgroundColor('blue')
}

在这里插入图片描述

@Entry
@Component
@Preview
struct Index {
  @State message: string = 'Hello World'



  aboutToAppear() {

  }

  build() {
    Column({ space: 20 }) {
      Text('曹操').MyTextStyle(Color.White)
      Text('孙坚').MyTextStyle(Color.Blue)
      Text('刘备').MyTextStyle(Color.Green)
      Text('吕布').MyTextStyle()
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}
//扩展原生样式,可以用私有的,可以传递参数,参数可以设置默认值,有默认值的写在最后面
@Extend(Text) function MyTextStyle(color:Color = Color.Orange) {
  .fontSize(50)
  .fontColor(color)
  .backgroundColor(Color.Gray)

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Entry
@Component
@Preview
struct Index {
  //定义状态变量
  @State count: number = 0

  build() {
    Column({ space: 20 }) {
       Text(`count =${this.count}`).fontSize(50)
      Button('点击加一').onClick(()=>{this.count++})
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

在这里插入图片描述

@Entry
@Component
@Preview
struct Index {
  //定义状态变量
  @State count: number = 0

  build() {
    Column({ space: 20 }) {
      Text(`父组件的count${this.count}`).fontSize(40)
      Button('父点击加一').onClick(() => {
        this.count++
      })
      Child({ childCount: this.count })

    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

@Component
struct Child {
  //把count传递给子组件Child,使用@Prop修饰

  @Prop private childCount: number

  build() {
    Column() {
      Text(`子组件的count${this.childCount}`).fontSize(40)
      //prop是单向同步,这里点击加一变得只有child组件,父组件不变
      Button('子点击加一').onClick(() => {
        this.childCount++
      })
    }
  }
}
@Entry
@Component
@Preview
struct Index {
  //定义状态变量
  @State count: number = 0

  build() {
    Column({ space: 20 }) {
      Text(`父组件的count${this.count}`).fontSize(40)
      Button('父点击加一').onClick(() => {
        this.count++
      })
      //@Link修饰的变量必须要加$
      Child({ childCount:$count})

    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

@Component
struct Child {
  //把count传递给子组件Child,使用@Prop修饰

  @Link private childCount: number

  build() {
    Column() {
      Text(`子组件的count${this.childCount}`).fontSize(40)
      //link是单向同步,这里点击加一变得父组件与子组件都会变
      Button('子点击加一').onClick(() => {
        this.childCount++
      })
    }
  }
}

@prop不能是数组、对象,但支持枚举类型,不允许初始化
@link支持类型比较多,详见上图

在这里插入图片描述
@Provider 和@Consume是生产者和消费者模式

@Entry
@Component
@Preview
struct Index {
  //定义状态变量
  @Provide count: number = 0

  build() {
    Column({ space: 20 }) {
      Text(`父组件的count ${this.count}`).fontSize(40)
      Button('父点击加一').onClick(() => {
        this.count++
      })
      //不需要传递参数了
      Child()
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

@Component
struct Child {
  @Consume count: number

  build() {
    Column() {
      Text(`子组件${this.count}`).fontSize(40)
      GrandSon()
    }
  }
}

@Component
struct GrandSon {
  @Consume count: number

  build() {
    Column() {
      Text(`孙组件${this.count}`).fontSize(40)
      Button('孙点击加一').onClick(() => {
        //孙组件点击改变count,父组件,子组件也会改变
        this.count++
      })
    }
  }
}

@Entry
@Component
@Preview
struct Index {
  @State grade:Grade = new Grade(new Student('孙悟空',18))
  build() {
    Column({ space: 20 }) {
      Text(`父组件中的name=${this.grade.stu.name},年龄=${this.grade.stu.age}`).fontSize(30)
      Button('父组件').onClick(()=>{
        this.grade.stu.age+=1
        console.log(`年龄${this.grade.stu.age}`)
      })
      Child({stu:this.grade.stu})
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}
//子组件
@Component
struct Child{
  //传递学生对象,增加@ObjectLink后,在父组件中点击修改年龄,子组件可以响应,也会修改
  @ObjectLink stu:Student
  build(){
    Column(){
      Text(`子组件中的name=${this.stu.name},年龄=${this.stu.age}`).fontSize(30)
    }
  }
}
//学生类,单独使用Observed没任何效果,需要搭配@ObjectLink或者@Prop
@Observed
class Student {
  name: string = ''
  age: number = 18

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
//年级
@Observed
class Grade {
   stu: Student

  constructor(stu: Student) {
    this.stu = stu;
  }
}

@Watch,监听某个值,一旦值变化了,会调用某个函数

@Entry
@Component
@Preview
struct Index {
  @State
  @Watch('myCallBack')//@Watch的作用是监听count的值,只要count值发生变化,myCallBack就会被回调一次
  count:number = 0
  @State message:string = '@Watch回调函数被第0次调用'
  build() {
    Column({ space: 20 }) {
      Text(this.message).fontSize(40).fontColor(Color.Green)
      Button('点击count+1').onClick(()=>{
        //如果这里注释掉,myCallBack函数不会调用,因为count值没有变化
        this.count++
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
  myCallBack(){
    console.log('callback被调用了');
  }
}

@Watch修饰的可以是类

@Entry
@Component
@Preview
struct Index {
  @State
  @Watch('myCallBack')//@Watch的作用是监听count的值,只要count值发生变化,myCallBack就会被回调一次
  person:Person = new Person(1)
  build() {
    Column({ space: 20 }) {
      Text(`${this.person.count}`).fontSize(40).fontColor(Color.Green)
      Button('点击count+1').onClick(()=>{
        //如果这里注释掉,myCallBack函数不会调用,因为count值没有变化
        this.person.count++
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
  myCallBack(){
    console.log('callback被调用了');
  }

}
class Person{
 count:number;

  constructor(count:number) {
    this.count = count;
  }
}

UI状态存储,上面讲述的是组件传值,组件传值是在一个界面传值,多个界面传值无法使用。
多个界面如下配置
在这里插入图片描述

import router from '@ohos.router'
@Entry
@Component
@Preview
struct Index {

  build() {
    Column({ space: 20 }) {

      Button('界面跳转').onClick(()=>{
        //界面跳转,
         router.pushUrl({url:'pages/Index2'})
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

界面跳转的写法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上代码:
在这里插入图片描述

//定义常量,购物车中存取都用这个键
export const Key: string = 'cart_key'
//添加购物车,这里直接使用string,不再新建一个类
export const addCart = (goods:string) => {
  //从购物车中取出对应的商品,从AppStorage中通过键取,没有值就给个空字符串
  const myGoods = AppStorage.Get(Key) as string || ''
  //字符串拼接下,
  let str = goods.concat(myGoods)
  //将购物车信息放入到AppStorage中
  AppStorage.SetOrCreate(Key,str)
}
//清空购物车
export const clearCart = ()=>{
  AppStorage.SetOrCreate(Key,'')
}
//不要忘记了export
import router from '@ohos.router'
@Entry
@Component
@Preview
struct Index {

  build() {
    Column({ space: 20 }) {

      Button('界面跳转').onClick(()=>{
        //界面跳转,
         router.pushUrl({url:'pages/GoodsPages'})
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

import promptAction from '@ohos.promptAction'
import router from '@ohos.router'
import { addCart } from '../tools/util'
@Entry
@Component
@Preview
struct GoodsPages {
  //商品页面
  build() {
    Column({ space: 20 }) {

      Button('苹果手机加入购物车').onClick(()=>{
              addCart('苹果手机')
        promptAction.showToast({message:"苹果购买成功"})
      })

      Button('华为手机加入购物车').onClick(()=>{
        addCart('华为手机')
        promptAction.showToast({message:"华为购买成功"})
      })
      Button('跳转到购物车界面').onClick(()=>{
        router.pushUrl({url:'pages/Index2'})
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }

}

上述代码有一个问题,数据没有持久化存储,观点app在重新打开,购物车里的商品会消失
在这里插入图片描述
需要持久化
//一句话实现持久化存储
PersistentStorage.PersistProp(Key,‘’)

import { Key } from '../tools/util'
//一句话实现持久化存储
PersistentStorage.PersistProp(Key,'')
@Entry
@Component
@Preview
struct Index2 {
  //购物车界面,有添加商品,跳转到别的界面,购物车信息依然可以共享
  //大部分的时候存储的是json字符串,AppStorage是存储在内存中,需要持久化
  @StorageProp(Key)//必须初始化,如果有值就取出来,如果没值就把初始化的值存入AppStorage
  cart:string = ''
  build() {
    Column({ space: 20 }) {
       Text(`购物车的商品:${this.cart}`).fontSize(30)

    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
   // test(){
   //   JSON.parse(this.cart)
   //   JSON.stringify()
   // }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在src/main/ets/entryability/EntryAbility.ts的onWindowStageCreate()中加载默认启动的界面
在这里插入图片描述
在这里插入图片描述
//组件在界面中的生命周期函数
//界面出现时候的回调
aboutToAppear(){}
//界面销毁时候的回调
aboutToDisappear(){}

import router from '@ohos.router'
@Entry
@Component
@Preview
struct Index {
  aboutToAppear(){
    console.log("马超","aboutToAppear")
  }
  aboutToDisappear(){
    console.log("马超","aboutToDisappear")
  }
  onPageShow(){
    console.log("马超","onPageShow")
  }
  onPageHide(){
    console.log("马超","onPageHide")
  }

  build() {
    Column({ space: 20 }) {

      Button('界面跳转').onClick(()=>{
        //界面跳转,
         router.pushUrl({url:'pages/GoodsPages'})
      })
    }.justifyContent(FlexAlign.Center).height('100%').width('100%')
  }
}

启动app时候的打印

06-09 16:53:36.367 20540-974/? I 0FEFE/JsApp: 马超 aboutToAppear
06-09 16:53:36.368 20540-974/? I 0FEFE/JsApp: 马超 onPageShow

屏幕息屏的时候调用

06-09 16:54:06.228 20540-974/com.example.myapplication I 0FEFE/JsApp: 马超 onPageHide

pushUrl时候的跳转

06-09 16:55:12.002 20540-974/com.example.myapplication I 0FEFE/JsApp: 马超 onPageHide

replaceUrl时候的跳转

06-09 16:56:29.723 22798-1042/com.example.myapplication I 0FEFE/JsApp: 马超 aboutToDisappear

退出app时候的跳转

06-09 16:56:29.723 22798-1042/com.example.myapplication I 0FEFE/JsApp: 马超 aboutToDisappear

只有@Component修饰而没有@Entry修饰的组件只有下面两个方法

  aboutToAppear(){
    console.log("马超","aboutToAppear")
  }
  aboutToDisappear(){
    console.log("马超","aboutToDisappear")
  }```
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/394fdc2d4ecb4f7f933328cd3fae3cfb.png)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694510.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

著名AI人工智能社会学家唐兴通谈数字社会学网络社会学主要矛盾与数字空间社会网络社会的基本议题与全球海外最新热点与关注社会结构社会分工数字财富数字游民数字经济

如果人工智能解决了一切,人类会做什么? 这个问题的背后是人工智能时代的社会主要矛盾会是什么?那么整个社会的大的分工体系就会围绕主要矛盾开展。 《人工智能社会主要矛盾》 在农业社会,主要矛盾是人口增长和土地资源之间的关…

这家叉车AGV巨头2024年一季度销售4075万~

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 一、BALYO公司概览 BALYO,这家来自法国的仓储机器人公司,自2006年成立以来,一直致力于为全球客户提供…

LabVIEW 与组态软件在自动化系统中的应用比较与选择

LabVIEW 确实在非标单机设备、测试和测量系统中有着广泛的应用,特别是在科研、教育、实验室和小型自动化设备中表现突出。然而,LabVIEW 也具备一定的扩展能力,可以用于更复杂和大型的自动化系统。以下是对 LabVIEW 与组态软件在不同应用场景中…

嵌入式单片机产品微波炉拆解分享

在厨房电器中,微波炉可以说是最具技术含量的电器,它的工作原理不像其他电器那样一眼就能看个明白,于是拆解了一个微波炉,分析内部电路。 微波炉的结构 微波炉由箱体、磁控管、变压器、高压电容器、高压二极管、散热风扇、转盘装置及一系列控制保护开关组成,大多数微波炉还…

【详细的Kylin使用心得,什么是Kylin?】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

【JAVASE】面向对象编程综合案例--------模仿电影信息系统

需求: (1)展示系统中的全部电影(每部电影展示:名称、价格) (2)允许用户根据电影编号(ID)查询出某个电影的详细信息。 目标:使用所学的面向对象…

报表或者BI的价值在哪?这是十几年的问题啦!

对,问题已经十几年了,答案也应该普世都懂了吧,但非常遗憾,答案没有问题普及的广。看似简单,但也难说清楚,不同的人,总会有不同的看法。 为什么要解释这个并不新鲜的问题? 因为有人问…

计网总结☞网络层

.................................................. 思维导图 ........................................................... 【Wan口和Lan口】 WAN口(Wide Area Network port): 1)用于连接外部网络,如互联…

Java面向对象-[封装、继承、多态、权限修饰符]

Java面向对象-封装、继承、权限修饰符 一、封装1、案例12、案例2 二、继承1、案例12、总结 三、多态1、案例 四、权限修饰符1、private2、default3、protected4、public 一、封装 1、案例1 package com.msp_oop;public class Girl {private int age;public int getAge() {ret…

【AI 高效问答系统】机器阅读理解实战内容

⭐️我叫忆_恒心,一名喜欢书写博客的研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支…

Git【版本控制命令】

02 【本地库操作】 1.git的结构 2.Git 远程库——代码托管中心 2.1 git工作流程 代码托管中心用于维护 Git 的远程库。包括在局域网环境下搭建的 GitLab 服务器,以及在外网环境下的 GitHub 和 Gitee (码云)。 一般工作流程如下: 1.从远程…

大模型创新企业集结!百度智能云千帆AI加速器Demo Day启动

新一轮技术革命风暴席卷而来,为创业带来源源不断的创新动力。过去一年,在金融、制造、交通、政务等领域,大模型正从理论到落地应用,逐步改变着行业的运作模式,成为推动行业创新和转型的关键力量。 针对生态伙伴、创业…

基于STM32开发的智能机器人导航系统

目录 引言环境准备智能机器人导航系统基础代码实现:实现智能机器人导航系统 4.1 距离传感器数据读取4.2 电机控制4.3 实时路径规划与避障4.4 用户界面与状态显示应用场景:智能机器人导航与控制问题解决方案与优化收尾与总结 1. 引言 智能机器人导航系…

五款软件推荐:U盘数据不小心删除了?帮你快速找回!

U盘数据不小心删除了怎么恢复?U盘是一种便携式存储设备,因其小巧轻便而广受欢迎。但是,U盘也常常会遇到数据丢失的问题。当U盘数据丢失时,需要找到一款可靠的数据恢复软件来恢复数据。 接下来为大家推荐5款好用的免费U盘数据恢复软…

Django更改超级用户密码

Django更改超级用户密码 1、打开shell 在工程文件目录下敲入: python manage.py shell再在python交互界面输入: from django.contrib.auth.models import User user User.objects.get(username root) user.set_password(123456) user.save()其中ro…

c++中, 直接写浮点数, 是float 还是 double?

如果直接一个浮点数, 那么他默认是float还是double呢? 测试用例 #include <iostream> using namespace std;int main() {auto x 0.2;float f 0.2;double d 0.2;cout << "x Size : " << sizeof(x) << " bytes" << endl…

关于人生规划(下)

&#xff08;关于人生规划(3)&#xff09; &#xff08;关于人生规划(4)&#xff09; 没有补充能量的后防线级别的大本营&#xff0c;是没办法长时间在外奋斗的。无论如何消耗能量&#xff0c;回到家里就可以补充能量。 无论你是单身还是结婚状态&#xff0c;家一定是一个非常温…

像素坐标系与图像坐标系

前言 在数字图像处理中&#xff0c;经常会看到使用 (x, y) 表示图像中的某个像素点。 在一些图像处理库&#xff0c;例如 Pillow 、OpenCV 、Numpy 中也会使用到坐标系处理图像的像素点。 介绍 无论是像素坐标系还是图像坐标系&#xff0c;其原理都是一样的&#xff1a; 以…

BC8 十六进制转十进制

BC8 十六进制转十进制 废话不多说上题目&#xff1a; 代码如下&#xff1a; #include<stdio.h> int main() {printf("%15d", 0XABCDEF);return 0; }这里总结下C语言的常见语法点&#xff1a; 1&#xff1a;%m.n&#xff0c;m表示整个数值占多少位包括小数点&am…

CloudFlare 防火墙规则里开放合法 Bot 爬虫的方法

明月使用 CloudFlare 也算是有一阵子了,可以说效果非常好更是非常满意,毕竟每天成千上万的 Web 攻击和 cc 攻击都能控制在几乎可以忽略不计的程度了,上次因调试需要关闭了国内线路上的网站卫士统计图覆对比就很能说明这点儿: 这是关闭防火墙当天的实时防御统计结果 这是开启…