鴻蒙開發:V2版本裝飾器之@Monitor裝飾器

前言

本文代碼案例基于Api13。

隨著官方的迭代,在新的Api中,對于新的應用開發,官方已經建議直接使用V2所屬的裝飾器進行開發了,所以,能上手V2的盡量上手V2吧,畢竟,V2是V1的增強版本,為開發者提供更多功能和靈活性,由V1升成V2,肯定是大勢所趨;但是,畢竟V1有著大量的應用基礎,使用的也非常廣泛,如果V1版本的功能和性能已能滿足需求,其實也不用切換,總之就一句話:新的應用盡量使用V2,老的應用,如果V1滿足可以不切換V2,如果功能受限,建議循序漸進的進行切換。

本篇文章主要概述下V2版本裝飾器中的@Monitor裝飾器,它對標的是V1中的@Watch裝飾器,但是使用上和功能上均有所不同。

記得之前在寫刷新組件的時候,有一個功能,需要監聽當前刷新或加載的關閉狀態,然后去執行關閉動畫等邏輯,使用的就是@Watch裝飾器,簡單的邏輯如下:

class RefreshController {closeRefresh: boolean = falsecloseLoadMore: boolean = false
}@Entry
@Component
struct Index {@State @Watch("listenerController") refreshController: RefreshController = new RefreshController()listenerController() {console.log("==當前刷新狀態:" + this.refreshController.closeRefresh)console.log("==當前加載狀態:" + this.refreshController.closeLoadMore)}build() {Column() {Button("關閉刷新").onClick(() => {this.refreshController.closeRefresh = true})Button("關閉加載").margin({ top: 20 }).onClick(() => {this.refreshController.closeLoadMore = true})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

運行后,我們點擊按鈕進行打印日志:

雖然執行的狀態,我們通過@Watch裝飾器監聽到了,也能實現我們的邏輯,但是存在一個問題,本身我們只想監聽到某一個狀態的改變,比如只監聽刷新狀態,或者只監聽加載狀態,但是@Watch裝飾器是,你無論監聽哪一個,都統統給你返回,顯然會影響我們做針對性的邏輯判斷。

除此之外,還存在一個問題,變量更改前的值是什么,在這里無法獲取,在業務邏輯復雜的場景下,我們是無法準確知道是哪一個屬性或元素發生了改變從而觸發了@Watch事件,這非常不便于我們對變量的更改進行準確監聽。

針對以上的弊端,V2版本中的@Monitor裝飾器,則彌補了這一缺陷,實現對對象、數組中某一單個屬性或數組項變化的監聽,并且能夠獲取到變化之前的值。

更改為@Monitor裝飾器后,針對屬性單獨監聽。

@ObservedV2
class RefreshController {@Trace closeRefresh: boolean = false@Trace closeLoadMore: boolean = false
}@Entry
@ComponentV2
struct Index {@Local refreshController: RefreshController = new RefreshController()@Monitor("refreshController.closeRefresh")closeRefreshChange() {console.log("==當前刷新狀態:" + this.refreshController.closeRefresh)}@Monitor("refreshController.closeLoadMore")closeLoadMoreChange() {console.log("==當前加載狀態:" + this.refreshController.closeLoadMore)}build() {Column() {Button("關閉刷新").onClick(() => {this.refreshController.closeRefresh = true})Button("關閉加載").margin({ top: 20 }).onClick(() => {this.refreshController.closeLoadMore = true})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

使用方式

首先需要注意,@Monitor監聽的變量,一定是被@Local、@Param、@Provider、@Consumer、@Computed裝飾,否則是無法監聽的,這一點,務必須知。

第一步,使用@Local、@Param、@Provider、@Consumer、@Computed等其中之一,修飾你的變量,例如下代碼:

@Local testContent: string = "測試數據一"

第二步,使用@Monitor裝飾器進行監聽,方法名自己定義,要求,@Monitor("變量名"),其中變量名一定要和第一步的變量名字保持一致,例如下代碼:

  @Monitor("testContent")testContentChange() {console.log("==屬性testContent發生了改變:" + this.testContent)}

動態改變屬性testContent,就會觸發@Monitor裝飾器修飾的函數;@Monitor裝飾器支持監聽多個狀態變量,直接逗號分隔即可,多個屬性中,任意一個屬性發生了改變都會進行回調。

@Monitor("testContent","testNumber")
testChange() {console.log("==testContent屬性:" + this.testContent + ",testNumber屬性:" + this.testNumber)}

獲取改變之前的值

如果你想拿到當前屬性改變之前的值,那么就需要在函數中傳遞IMonitor類型的參數。

IMonitor類型的變量用作@Monitor裝飾方法的參數。

屬性

類型

參數

返回值

說明

dirty

Array<string>

保存發生變化的屬性名。

value<T>

function

path?: string

IMonitorValue<T>

獲得指定屬性(path)的變化信息。當不填path時返回@Monitor監聽順序中第一個改變的屬性的變化信息。

MonitorValue<T>類型

IMonitorValue<T>類型保存了屬性變化的信息,包括屬性名、變化前值、當前值。

屬性

類型

說明

before

T

監聽屬性變化之前的值。

now

T

監聽屬性變化之后的當前值。

path

string

監聽的屬性名。

  @Monitor("testContent")testChange(monitor: IMonitor) {monitor.dirty.forEach((path: string) => {console.log("==屬性值改變之前:" + monitor.value(path)?.before + ",屬性值改變之后:" + monitor.value(path)?.now)})}

如果只想監聽改變之后的值,IMonitor參數可以省略。

對象監聽

在前言中,我們可以看到,監聽對象中的屬性變化時,需要使用@Trace裝飾,如果未被裝飾,則是無法進行監聽的,所以在實際的開發中,如果需要針對對象的單一屬性進行監聽時,@Trace裝飾務必使用。

如果不裝飾,那么就需要重新創建對象,雖然這種方式也能正常的監聽到,但是并不是唯一屬性的監聽,在實際的開發中是不推薦的。

以下案例未使用@Trace裝飾,不建議使用。

class RefreshController {closeRefresh: boolean = falsecloseLoadMore: boolean = false
}@Entry
@ComponentV2
struct Index {@Local refreshController: RefreshController = new RefreshController()@Monitor("refreshController.closeRefresh")closeRefreshChange() {console.log("==當前刷新狀態:" + this.refreshController.closeRefresh)}@Monitor("refreshController.closeLoadMore")closeLoadMoreChange() {console.log("==當前加載狀態:" + this.refreshController.closeLoadMore)}build() {Column() {Button("關閉刷新").onClick(() => {this.refreshController = new RefreshController()this.refreshController.closeRefresh = true})Button("關閉加載").margin({ top: 20 }).onClick(() => {this.refreshController = new RefreshController()this.refreshController.closeLoadMore = true})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

如果你想監聽整個對象的屬性變化,@Trace裝飾可以不使用。

class RefreshController {closeRefresh: boolean = falsecloseLoadMore: boolean = false
}@Entry
@ComponentV2
struct Index {@Local refreshController: RefreshController = new RefreshController()@Monitor("refreshController")statusChange() {console.log("==當前刷新狀態:" + this.refreshController.closeRefresh)console.log("==當前加載狀態:" + this.refreshController.closeLoadMore)}build() {Column() {Button("關閉刷新").onClick(() => {this.refreshController = new RefreshController()this.refreshController.closeRefresh = true})Button("關閉加載").margin({ top: 20 }).onClick(() => {this.refreshController = new RefreshController()this.refreshController.closeLoadMore = true})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

除了在UI組件可以進行監聽,在自身對象中也是可以進行監聽的,方便在對象中做一些邏輯,同樣也支持在繼承類場景下,同一個屬性進行多次監聽。

@ObservedV2
class RefreshController {@Trace closeRefresh: boolean = false@Trace closeLoadMore: boolean = false@Monitor("closeRefresh")closeRefreshChange() {console.log("==監聽對象中的當前刷新狀態:" + this.closeRefresh)}
}

通用監聽能力

@Monitor裝飾器,除了正常的數據監聽之外,還支持對數組中的元素進行監聽,包括多維數組,對象數組,雖然可以正常監聽其值的變化,但是無法監聽內置類型(Array、Map、Date、Set)的API調用引起的變化。

還有一點需要注意,當@Monitor監聽數組整體變化時,只能通過監聽數組的長度變化來判斷數組是否有插入、刪除等變化,以下是一個簡單的二位數組數據改變案例:

@Entry
@ComponentV2
struct Index {@Local numberArray: number[][] = [[1, 1, 1], [2, 2, 2], [3, 3, 3]];@Monitor("numberArray.0.0", "numberArray.1.1")statusChange() {console.log("==數據改變:" + this.numberArray)}build() {Column() {Button("改變").onClick(() => {this.numberArray[0][0]++})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

可以發現以上的案例,只要數據發生了變化,就會執行數據監聽方法。

監聽對象整體改變時,如果當前屬性未發生改變時,則不會觸發@Monitor回調。

如下案例,依次點擊按鈕,會發生,按鈕一不會執行任何方法,因為屬性的值一樣,未發生變化,按鈕二和按鈕三則可以正常執行。

@ObservedV2
class RefreshController {@Trace closeRefresh: boolean = false@Trace closeLoadMore: boolean = falseconstructor(closeRefresh: boolean, closeLoadMore: boolean) {this.closeRefresh = closeRefresh;this.closeLoadMore = closeLoadMore;}
}@Entry
@ComponentV2
struct Index {@Local refreshController: RefreshController = new RefreshController(false, false)@Monitor("refreshController.closeRefresh")closeRefreshChange() {console.log("==當前刷新狀態:" + this.refreshController.closeRefresh)}@Monitor("refreshController.closeLoadMore")closeLoadMoreChange() {console.log("==當前加載狀態:" + this.refreshController.closeLoadMore)}build() {Column() {Button("不會走").onClick(() => {this.refreshController = new RefreshController(false, false)})Button("關閉刷新").margin({ top: 20 }).onClick(() => {this.refreshController = new RefreshController(true, false)})Button("關閉加載").margin({ top: 20 }).onClick(() => {this.refreshController = new RefreshController(false, true)})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

相關總結

如果要實現@Monitor監聽,其變量一定要被@Local、@Param、@Provider、@Consumer、@Computed裝飾,未被修飾則無法被監聽,還有,如果監聽對象的變化,則不建議在一個類中對同一個屬性進行多次@Monitor的監聽,多次監聽,只有最后一個定義的監聽方法才會有效。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71400.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71400.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71400.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

國產編輯器EverEdit - 獨門暗器:自動監視剪貼板內容

1 監視剪貼板 1.1 應用場景 如果需要對剪貼板的所有歷史進行記錄&#xff0c;并進行分析和回顧&#xff0c;則可以使用監視剪貼板功能&#xff0c;不僅在EverEdit中的復制會記錄&#xff0c;在其他應用的復制也會記錄。 1.2 使用方法 新建一個空文檔(重要&#xff1a;防止擾亂…

pdf轉換成word在線 簡單好用 支持批量轉換 效率高 100%還原

pdf轉換成word在線 簡單好用 支持批量轉換 效率高 100%還原 在數字化辦公的浪潮中&#xff0c;文檔格式轉換常常讓人頭疼不已&#xff0c;尤其是 PDF 轉 Word 的需求極為常見。PDF 格式雖然方便閱讀和傳輸&#xff0c;但難以編輯&#xff0c;而 Word 格式卻能靈活地進行內容修…

深入探索C語言中的字符串處理函數:strstr與strtok

在C語言的字符串處理領域&#xff0c; strstr 和 strtok 是兩個非常重要的函數&#xff0c;它們各自承擔著獨特的功能&#xff0c;為開發者處理字符串提供了強大的支持。 一、strstr函數&#xff1a;字符串查找的利器 strstr 函數用于在一個字符串中查找另一個字符串的首次出現…

AIGC(生成式AI)試用 21 -- Python調用deepseek API

1. 安裝openai pip3 install openai########################## Collecting openaiUsing cached openai-1.61.1-py3-none-any.whl.metadata (27 kB) Collecting anyio<5,>3.5.0 (from openai)Using cached anyio-4.8.0-py3-none-any.whl.metadata (4.6 kB) Collecting d…

關于使用雪花算法生成唯一ID,返回給前端ID不一致的問題

問題 在某個項目中,使用雪花算法生成的唯一ID,從數據庫查詢到數據后返回給前端,但是前端接受到的數據ID和數據庫原先生成的不一致 但是前端展示的數據: 原因 原因是后端使用Long類型來存儲雪花算法生成的ID,但是這個數值已經超過前端數值類型的范圍,導致前端在存儲這個數值…

Windows 啟動 SSH 服務

Windows 啟動 SSH 服務 一、OpenSSH Server 安裝 以 Win10 系統為例 打開設置 -> 系統 -> 可選功能 在 添加的功能 查看是否安裝了 OpenSSH 服務 或者 OpenSSH Server 如果沒有安裝&#xff0c;找到 系統->添加可選功能 -> 查看功能->搜索 OpenSSH 服務 ->…

C#功能測試

List 內部元素為引用 src[0]為"11" List<Source> src new List<Source>(); src.Add(new Source() { Name "1", Age 1, Description "1" }); src.Add(new Source() { Name "2", Age 2, Description "2"…

大數據SQL調優專題——Flink執行原理

引入 上一篇我們了解了Spark&#xff0c;相比起MapReduce來說&#xff0c;它確實已經快了超級多了&#xff0c;但是人類的欲望是沒有止境的&#xff0c;這也是推動人類進步的動力。 Flink就是為了滿足實時響應的場景需求誕生的。 其實在Flink之前&#xff0c;實時處理其實已…

計算機視覺:神經網絡實戰之手勢識別(附代碼)

第一章&#xff1a;計算機視覺中圖像的基礎認知 第二章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(一) 第三章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(二) 第四章&#xff1a;搭建一個經典的LeNet5神經網絡(附代碼) 第五章&#xff1…

win11安裝wsl報錯:無法解析服務器的名稱或地址(啟用wsl2)

1. 啟用wsl報錯如下 # 查看可安裝的 wsl --install wsl --list --online此原因是因為沒有開啟DNS的原因&#xff0c;所以需要我們手動開啟DNS。 2. 按照如下配置即可 Google的DNS&#xff08;8.8.8.8和8.8.4.4) 全國通用DNS地址 (114.114.114.114) 3. 運行以下命令來重啟 WSL…

開源模型應用落地-DeepSeek-R1-Distill-Qwen-7B-LoRA微調-LLaMA-Factory-單機單卡-V100(一)

一、前言 如今&#xff0c;大語言模型領域熱鬧非凡&#xff0c;各種模型不斷涌現。DeepSeek-R1-Distill-Qwen-7B 模型憑借其出色的效果和性能&#xff0c;吸引了眾多開發者的目光。而 LLaMa-Factory 作為強大的微調工具&#xff0c;能讓模型更好地滿足個性化需求。 在本篇中&am…

k8s-對接NFS存儲

一、前提條件 1、NFS_Server 部署好了。 2、網絡可達。 二、 使用方式 1、CSI **項目地址 https://github.com/kubernetes-csi/csi-driver-nfs#readme Install NFS CSI driver v4.10.0 version on a kubernetes cluster If you have already installed Helm, you can a…

【動態路由】系統Web URL資源整合系列(后端技術實現)【nodejs實現】

需求說明 軟件功能需求&#xff1a;反向代理功能&#xff08;描述&#xff1a;apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 業務應用等多個web資…

Git 修改或刪除某次提交信息

Git 修改或刪除某次提交信息 情況一&#xff1a;未推送到遠程倉庫修改提交信息刪除提交信息&#xff08;替換為空信息&#xff09;修改歷史提交信息刪除歷史提交信息 情況二&#xff1a;已推送到遠程倉庫修改最新提交信息并推送到遠程倉庫修改歷史提交信息并推送到遠程倉庫 情況…

DeepSeek崛起:如何在云端快速部署你的專屬AI助手

在2025年春節的科技盛宴上&#xff0c;DeepSeek因其在AI領域的卓越表現成為焦點&#xff0c;其開源的推理模型DeepSeek-R1擅長處理多種復雜任務&#xff0c;支持多語言處理&#xff0c;并通過搜索引擎獲取實時信息。DeepSeek因其先進的自然語言處理技術、廣泛的知識庫和高性價比…

DeepSeek部署到本地(解決ollama模型下載失敗問題)

一、下載ollama軟件安裝 1、下載ollama軟件 Ollama 下載完成后可以直接進行安裝&#xff08;外網&#xff0c;速度可能會有點慢&#xff09; 2、修改安裝目錄 進去下載的目錄&#xff0c;使用cmd打開終端輸入OllamaSetup.exe /DIRE:\MySoftware\Ollama 輸入完成后會自動打開…

GPT1 大模型

GPT1 大模型 模型架構訓練過程 GPT-1 : 采用傳統的語言模型方法進行預訓練&#xff0c;擅長處理自然語言生成任務&#xff08;NLG&#xff09;OpenAI 在 2018 年 6 月推出 1.17 億個參數的 GPT-1 (Generative Pre-training , 生成式預訓練) 數據集 : 數據來源 : BooksCorpus…

?1.HTML、CSS 和 JavaScript 是什么?

?? HTML、CSS 和 JavaScript 是構建網頁的三大核心技術&#xff0c;它們相互協作&#xff0c;讓網頁呈現出豐富的內容、精美的樣式和交互功能。以下為你詳細介紹&#xff1a; &#x1f98b;1. HTML&#xff08;超文本標記語言&#xff09; 定義&#xff1a;HTML 是一種用于描…

x86平臺基于Qt+opengl優化ffmpeg軟解碼1080P視頻渲染效率

一般的在arm嵌入式平臺&#xff0c;大多數板子都要硬解碼硬件渲染的框架&#xff0c;使用即可。 在x86下比較麻煩了。 優化的思路一共有以下幾個方面&#xff0c; 1. 軟解碼變成硬解碼 2. 將YUV轉QImage的操作轉移到GPU 3. QWidget渲染QImage變成opengGL渲染AVFrame 這三點…

ocr智能票據識別系統|自動化票據識別集成方案

在企業日常運營中&#xff0c;對大量票據實現數字化管理是一項耗時且容易出錯的任務。隨著技術的進步&#xff0c;OCR&#xff08;光學字符識別&#xff09;智能票據識別系統的出現為企業提供了一個高效、準確的解決方案&#xff0c;不僅簡化了財務流程&#xff0c;還大幅提升了…