学习鸿蒙基础(7)

news2024/11/15 10:50:48

一、@Watch状态变量更改通知
@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。
1、装饰器参数:必填。常量字符串,字符串需要有引号。是(string)=> void自定义成员函数的方法的引用。
2、可装饰的自定义组件变量:装饰器@State、 @Prop、@Link、@ObjectLink、@Provide、 @Consume、@StorageProp以及@StorageLink所装饰的变量均可以通过@Watch监听其变化。不允许监听常规变量。
3、装饰器的顺序:建议@State、@Prop、@Link等装饰器在@Watch装饰器之前。

示例代码:模拟购物车多选效果。显示多选的数量展示。选中的时候通过watch去监听到选中的状态。更新ui

import myList from '../components/myListWatch'
import Item from '../model/ItemFlag'

@Entry
@Component
struct PageWatch {
  @State text: string = ''
  @Provide list: Item [] = [
    new Item(Date.now(), "房子"),
    new Item(Date.now(), "车子")
  ]

  build() {
    Row() {
      Column() {
        Row(){
          Row() {
            CheckboxGroup({ group: "checkBoxGroup" })
            Text("全选")
            Button("删除").onClick(v => {
              this.list = this.list.filter(v =>!v.isChecked)
            }).margin({ left: "20" }).backgroundColor(Color.Red)

          }.margin({ top: "10", left: '20' })
          Summary()
        }.width("100%").justifyContent(FlexAlign.SpaceBetween)


        Row() {
          TextInput({ text: this.text }).width(250).onChange((value) => {
            this.text = value
          })
          Button("增加").onClick(() => {
            this.list.push(new Item(Date.now(), this.text))
            this.text = ""
          }).margin(10)
        }.width("100%").justifyContent(FlexAlign.SpaceBetween).margin(10)

        if (this.list.length) {
          ThisList()
        } else {
          Text("可你却总是笑我,一无所有")
        }

      }.width('100%')
      .height('100%')
    }
  }
}

@Component
struct ThisList {
  @Consume list: Item[];

  build() {
    Row() {
      List() {
        ForEach(this.list, (item, index) => {
          ListItem() {
            myList({ item, index })
          }.margin(10)
        })
      }.layoutWeight(1).divider({
        strokeWidth: 1,
        color: Color.Blue,
        startMargin: 10,
        endMargin: 10
      })
      .width('100%')
    }
  }
}

@Component
struct Summary {
  @Consume list: Item[];

  build() {
    Row() {
      Text(`${this.getchecked()}/${this.getTotal()}`).fontSize(26).margin({'left':14})
    }
  }

  getchecked(){
    return this.list.filter(item=>item.isChecked).length
  }

  getTotal(){
    return this.list.length
  }
}


import Item from '../model/ItemFlag';
//自定义组件  组件与组件之间是隔离的
@Component
struct myListWatch {
  @Consume list: Item [];//把list注入进来  不用去传递了
  @ObjectLink @Watch("onItemChecked") item: Item;
  private index: number;

  onItemChecked(){
    console.log("checked")
    this.list.splice(this.index,1,this.item)//删除当前的对象,在插入一个改变了的对象
  }

  build() {
    Row() {
      Checkbox({group:"checkBoxGroup"}).select(this.item.isChecked).onChange(v=>{
        this.item.isChecked=v
        console.log(JSON.stringify(this.item))
      })
      Text(this.item.text).fontSize(20).decoration(
        {type:this.item.isChecked?TextDecorationType.Underline:TextDecorationType.None,
          color:Color.Blue}
      )
      Button("删除").backgroundColor(Color.Red).onClick(() => {
        this.list.splice(this.index, 1)
      })
    }.justifyContent(FlexAlign.SpaceBetween).width("100%")
  }
}

export default myListObserved
@Observed class ItemFlag {
  id: number;
  text: string;
  isChecked:boolean;

  constructor(id: number, text: string,isChecked=false) {
    this.id = id
    this.text = text
    this.isChecked=isChecked
  }
}

export  default ItemFlag

二、页面间共享状态-LocalStorage

LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LoalStorage实例。LocalStorage也可以在UIAbility内,页面间共享状态。
LocalStorage根据与@Component装饰的组件的同步类型不同,提供了两个装饰器:
@LocalStorageProp: @LocalStorageProp装饰的变量和与LocalStorage中给定属性建立单向同步关系。
@LocalStorageLink:  @LocalStorageLink装饰的变量和在@Component中创建与LocalStorage中给定属性建立双向同步关系。

import router from '@ohos.router'
let storage=LocalStorage.GetShared()
@Entry(storage)
@Component
struct PageLocalStorage {
  @State message: string = 'Hello World'
  // @LocalStorageProp("name") n: string = ''
  @LocalStorageLink("name") n: string = ''
  build() {
    Row() {
      Column() {
        Text(this.n)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button("跳转").onClick(v => {
          router.pushUrl({
            url:"pages/PageLSDetail"
          })
        })
        Son1()
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct  Son1{
  @LocalStorageLink("name") m:string =""
  build(){
    Row(){
       Text(`child-${this.m}`)
    }
  }
}
import router from '@ohos.router'

let storage=LocalStorage.GetShared()
@Entry(storage)
@Component
struct PageLSDetail {
  @State message: string = 'Hello World'
  @LocalStorageLink("name") name:string=''

  build() {
    Row() {
      Column() {
        Text(this.name)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        Button("返回").onClick(v => {
          this.name="車子"
          router.back()
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  storage:LocalStorage =new LocalStorage({name:"房子"})
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/PageLocalStorage', this.storage,(err, data) => {
      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. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

三、AppStorage-应用全局的UI状态存储-非持久化

AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。仅仅存储在内存当中。退出程序后。数据就丢失了。
AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。
Appstorage可以和UI组件同步,且可以在应用业务逻辑中被访问。

    AppStorage.SetOrCreate("name","房子")
  @StorageProp("name") name:string =""

 

  @StorageLink("name") appname: string = ''

 四、PersistentStorage-持久化存储UI状态

PersistentStorage是应用程序中的可选单例对象。此对象的作用是持久化存储选定的AppStorage属性,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。
PersistentStorage允许的类型和值有:
1、number,stringboolean,enum 等简单类型
2、可以被SON.stringify0和SON.parse0重构的对象。例如Date, Map, Set等内置类型则不支持,以及对象的属性方法不支持持久化了
注意:
PersistentStorage的持久化变量最好是小于2kb的数据,不要大量的数据持久化,因为PersistentStorage写入磁盘的操作是同步的,大量的数据本地化读写会同步在UI线程中执行,影响UI渲染性能。如果开发者需要存储大量的数据,建议使用数据库api。
PersistentStorage只能在UI页面内使用,否则将无法持久化数据。

//只能在page页面中,才能持久化。
PersistentStorage.PersistProp("name","房子")
  @StorageProp("name") name:string =""

 

  @StorageLink("name") appname: string = ''

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么电商系统一定要跟企业ERP做数据对接?

一篇文章告诉你,为什么电商系统一定要跟企业ERP做数据对接? 在电商日益发展的情况下,每个电商企业的单量越来越大。但是电商系统对于财务来说并不友好,所以企业会另外上一套财务系统方便财务做账和企业内部管理。那如果还是按照之…

vue2 和 vue3 配置路由有什么区别

vue2 和 vue3 配置路由有什么区别 初始化路由器实例:注入到应用中:动态路由参数和捕获所有路由:编程式导航 API:异步加载组件: vue2 如何 使用路由 第一步:安装 vue-router第二步:创建路由组件第…

Java 基础知识- 创建线程的几种方式

大家好我是苏麟 , 今天聊聊创建线程的几种方式 . 创建线程的几种方式 1. 继承Thread类实现多线程 /*** className: ThreadTest* author: SL 苏麟**/ public class ThreadTest extends Thread{public static void main(String[] args) {ThreadTest threadTest new ThreadTes…

【Flutter 面试题】Flutter中的状态管理方案有哪些?请解释其中的一个

【Flutter 面试题】Flutter中的状态管理方案有哪些?请解释其中的一个 文章目录 写在前面口述回答补充说明准备工作实现待办事项模型实现待办事项列表模型构建 UI运行结果详细说明 写在前面 🙋 关于我 ,小雨青年 👉 CSDN博客专家&…

政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(三)—— 随机梯度下降

政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 这篇文章中,咱们将使用Keras和TensorFlow…

RAFT: Adapting Language Model to Domain Specific RAG

预备知识 RAG介绍一文搞懂大模型RAG应用(附实践案例) - 知乎 (zhihu.com) RAG的核心理解为“检索生成” 检索:主要是利用向量数据库的高效存储和检索能力,召回目标知识; 生成:利用大模型和Prompt工程&a…

今天聊聊Docker

在数字化时代,软件应用的开发和部署变得越来越复杂。环境配置、依赖管理、版本控制等问题给开发者带来了不小的挑战。而Docker作为一种容器化技术,正以其独特的优势成为解决这些问题的利器。本文将介绍Docker的基本概念、优势以及应用场景,帮…

前缀和(三)

题目:激光炸弹 1 链接 P2280 [HNOI2003] 激光炸弹 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 2.大体思路 先开辟一个全局变量的 s 二维数组,这个二维数组开成 s [ 5010 ] [ 5010 ] ,这个是为了,能够将它所给的所有有价值的…

由vue2版本升级vue3版本遇到的问题

一、vuedraggable 由vue2版本升级vue3版本后,可能会遇到以下几种bug: 1、vue3vuedraggable报错TypeError: Cannot read properties of undefined (reading ‘updated’):这个一般是因为插件使用语法有问题,vue3版本的插件使用时&…

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中,可能开发某个功能不需要了,或者想要回退到之前历史的某个commit, 放弃后来修改的内容。 放弃已修改的内容 如果未提交,直接使用 …

一个优秀的开源ChatGpt外壳项目(lobe-chat)

lobe-chat 简介: 开源、现代化设计的 ChatGPT/LLMs 聊天应用与开发框架支持语音合成、多模态、可扩展的插件系统,一键免费拥有你自己的 ChatGPT/Gemini/Ollama 应用。 下载lobe-chat lobe-chat项目开源地址:GitHub - lobehub/lobe-chat: &am…

[Linux]文件缓冲区

文件fd 输出重定向除了用dup2()改变数组下标外&#xff0c;还可以用命令来完成 所有的命令执行&#xff0c;都必须有操作系统将其运行起来变成进程&#xff0c;然后根据>>, <<来判断是输入重定向&#xff0c;还是输出重定向。 缓冲区 之所以有缓冲区&#xff0…

Jenkins+Ant+Jmeter接口自动化集成测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、Jenkins安装配置 1、安装配置JDK1.6环境变量&#xff1b; …

mysql事务及存储引擎

目录 什么是事务 事务的ACIP特性 事务之间的影响 mysql隔离级别 事务隔离级别的作用范围 事务控制语句 mysql存储引擎 什么是事务 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作…

STM32—控制蜂鸣器(定时器)

目录 1 、 电路构成及原理图 2 、编写实现代码 main.c tim_irq.c 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 定时器中断是利用定时器的计数功能&#xff08;向上计数或向下计…

Web前端—CSS属性计算过程

属性计算过程 CSS 属性计算过程1. 确定声明值2. 层叠冲突比较源的重要性比较优先级比较次序 3. 使用继承4. 使用默认值 CSS 属性计算过程 我们所书写的任何一个 HTML 元素&#xff0c;实际上都有完整的一整套 CSS 样式&#xff08;该元素上面会有 CSS 所有的属性。&#xff0…

Windows 7 一键恢复 - 联想拯救系统

Windows 7 一键恢复 - 联想拯救系统 1. 联想拯救系统1.1. OEM 分区1.2. 一键恢复 References 1. 联想拯救系统 1.1. OEM 分区 计算机 -> 管理 -> 存储 -> 磁盘管理 1.2. 一键恢复 重新启动电脑 F11 -> 从初始备份恢复 References [1] Yongqiang Cheng, https…

实在数字员工,助力菜鸟智慧物流高效腾飞,领航行业新高度

秉承人人都有一个智能助理的发展愿景&#xff0c;自2023年首个数字员工落地以来&#xff0c;菜鸟数字员工累计运行时长已达10万小时。 在智能物流科技不断飞速迭代的今天&#xff0c;物流行业作为社会经济运行的重要支柱和电子商务生态链的关键环节&#xff0c;面临着前所未…

Python灰帽子网络安全实践

教程介绍 旨在降低网络防范黑客的入门门槛&#xff0c;适合所有中小企业和传统企业。罗列常见的攻击手段和防范方法&#xff0c;让网站管理人员都具备基本的保护能力。Python 编程的简单实现&#xff0c;让网络运维变得更简单。各种黑客工具的理论和原理解剖&#xff0c;让人知…

PLC常用通信协议应用

PLC通信协议 ModbusModbus协议介绍Modbus协议的应用Modbus通信模式 Modbus RTU通讯Modbus RTU报文映射寄存器常见功能码数据类型Modbus CRC校验计算Modbus RTU举例&#xff08;读位&#xff09;Modbus RTU举例&#xff08;读字&#xff09; Modbus TCP协议应用TCP数据帧Modbus …