HarmonyOS开发实战( Beta5.0)自定义装饰器实践规范

介绍

本示例介绍通过自定义装饰器在自定义组件中自动添加inspector (布局回调)方法并进行调用。

效果图预览

不涉及

使用说明

  1. 在自定义组件上添加自定义装饰器@CallbackObserver,并根据参数设置对应的方法名和需要绑定的组件的ID。
  2. 编译工程,可以根据自定义装饰器生成方法并调用。
具体使用方法
  1. 在工程的hvigor-config.json5中配置插件。

    {..."dependencies": {..."@app/ets-decoration": "file:../libs/autobuilddecoration-1.0.0.tgz"}
    }
    
  2. 在需要使用自定义装饰器的模块的hvigorfile.ts中添加依赖和文件路径。

    import { harTasks } from '@ohos/hvigor-ohos-plugin';
    import { DecorationPluginConfig, etsDecorationPlugin } from '@app/ets-decoration';const config: PluginConfig = {scanFiles: [""],
    }
    export default {system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */plugins: [etsDecorationPlugin(config)]         /* Custom plugin to extend the functionality of Hvigor. */
    }
    
  3. 在自定义组件上添加自定义装饰器@CallbackObserver,并设置对应的方法名和组件ID。

    @CallbackObserver({onDraw: 'onDraw',onLayout: 'onLayout',offDraw: 'offDraw',offLayout: 'offLayout',bindId: 'text'
    })
    @Component
    export struct MainPage {build() {Column() {Text("Hello World").id('text')}}
    }
    
  4. 编译工程,即可生成对应的方法和调用代码。

实现思路

  1. 在ArkTS侧实现自定义装饰器,并配置需要的参数。

    // 自定义装饰器
    export function AutoAddInspector(param: InspectorParam) {return Object;
    }
    // 装饰器参数
    export interface InspectorParam {// inspector中onDraw需要配置的回调方法onDraw?: string;// inspector中onLayout需要配置的回调方法onLayout?: string;// inspector中offDraw需要配置的回调方法offDraw?: string;// inspector中offLayout需要配置的回调方法offLayout?: string;// 需要绑定的组件的IDbindId?:string;
    }
    
  2. 通过hvigorfile.ts中的配置,将使用自定义装饰器的文件路径传到插件中。

    import { DecorationPluginConfig, etsDecorationPlugin } from '@app/ets-decoration-generator';const config: DecorationPluginConfig = {// 配置自定义装饰器的文件路径scanFiles: ["src/main/ets/components/MainPage"],
    }export default {system: harTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */plugins:[etsDecorationPlugin(config)]         /* Custom plugin to extend the functionality of Hvigor. */
    }
    
  3. 将传入的文件解析为TypeScript抽象语法树,得到所有的节点信息。详细代码可参考Index.ts。

    start() {// 读取文件const sourceCode = readFileSync(this.sourcePath, "utf-8");// 解析文件,生成节点树信息const sourceFile = ts.createSourceFile(this.sourcePath, sourceCode, ts.ScriptTarget.ES2021, false);// 遍历节点信息ts.forEachChild(sourceFile, (node: ts.Node) => {// 解析节点console.log(JSON.stringify(node));this.resolveNode(node);});
    }
    
  4. 遍历节点,获取自定义装饰器中配置的参数,将方法名存入到列表中。

    // 解析装饰器
    resolveDecoration(node: ts.Node) {...if ((propertie.name as ts.StringLiteral).text !== 'bindId') {// 如果参数名不是“bindId”,则放入需要创建的方法列表中let methodInfo: MethodInfo = new MethodInfo();methodInfo.name = (propertie.name as ts.StringLiteral).text;methodInfo.value = (propertie.initializer as ts.StringLiteral).text;decoratorInfo.methods.push(methodInfo);this.methodArray.push((propertie.initializer as ts.StringLiteral).text);} else {// 如果参数名是“buildId”,则设置到对应的变量中decoratorInfo.bindId = (propertie.initializer as ts.StringLiteral).text;}...this.decorationInfos.push(decoratorInfo);...      
    }
    
  5. 遍历节点,记录aboutToAppear()方法的位置,并和第4步中存储的列表进行比较,过滤已经存在的方法,防止生成同名方法。

    // 解析装饰器装饰的自定义组件(从“{”到“}”)
    resolveBlock(node: ts.Node) {...// 自定义组件中已经存在的方法列表const methodNameArray: string[] = [];statements.forEach((statement: ts.Statement) => {...const identifier = callExpression.expression as Identifier;methodNameArray.push(identifier.escapedText.toString());// 查找是否已经存在aboutToAppear方法if (identifier.escapedText === 'aboutToAppear') {this.aboutToAppearExist = true;this.positionOfAboutToAppear = statement.pos;}...})// 过滤已经存在的装饰器中的方法const temp = this.methodArray.filter((value: string, index: number) => {return !methodNameArray.includes(value);})this.methodArray = temp;// 记录自定义组件的结束位置this.positionOfBlockEnd = node.end;}
    }
    
  6. 根据解析结果,生成方法代码和相关调用代码,并写入原文件中。

    function pluginExec(config: DecorationPluginConfig) {...// 开始解析文件analyzer.start();// 如果解析的文件中存在装饰器,则将结果保存到列表中if (analyzer.routerAnnotationExisted) {// 如果有需要创建的方法if (analyzer.methodArray.length > 0) {...// 装饰器中如果设置了bindId,则添加listener变量,并在aboutToAppear中调用监听方法// aboutToAppear方法是否已存在 if (analyzer.aboutToAppearExist) {// 如果已经存在aboutToAppear,则根据aboutToAppear方法的位置拆分结构体,并将需要生成的代码添加到对应的位置...} else {// 如果不存在aboutToAppear方法,则创建aboutToAppear方法,并添加调用代码...}// 根据模板创建装饰器中配置的方法...// 将生成的代码写入文件中writeFileSync(sourcePath, fileContent, { encoding: "utf8" })}}...
    }
    

工程结构&模块类型

customdecoration                               // har类型
|---components
|   |---CallbackObserver.ets                   // 自定义装饰器
|   |---MainPage.ets                           // UI页面

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为体系杂乱无章,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)路线、视频、文档用来跟着学习是非常有必要的。

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员

鸿蒙 NEXT 全栈开发学习笔记 希望这一份鸿蒙学习文档能够给大家带来帮助~


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频教程+学习PDF文档

(鸿蒙语法ArkTS、TypeScript、ArkUI教程……)

 纯血版鸿蒙全套学习文档(面试、文档、全套视频等)

                   

鸿蒙APP开发必备

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

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

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

相关文章

四款音频剪辑软件免费使用,你更pick哪一个?

视频剪辑知随着软件的不断更新,入门门槛和操作难度也随之变得越来越低,但是依然有不少人不知道剪辑视频要用什么工具,作为一个视频剪辑爱好者,我尝试过不少编辑软件,今天就来跟大家分享一下四款视频剪辑软件在实际使用…

adb devices不显示连接设备怎么解决

adb devices不显示设备,首先用老办法检查。假如是显示adb这个命令不认识,那就是系统路径问题。假如能认识adb这个命令,那就检查一下手机有没有开usb调试。 但是我遇到了更奇怪的问题:我把网上的攻略都试了一遍,设备驱…

通用四期ARM架构银河麒麟桌面操作系统V10【安装、配置FTP客户端】

一、操作环境 服务端:银河麒麟桌面操作系统V10SP1 客户端:银河麒麟桌面操作系统V10SP1 二、服务端配置 注:以下命令均在终端执行 鼠标点击桌面右键,选择打开终端 操作步骤: 1、安装vsftpd软件:如果提…

深入理解TCP三次握手

在网络通信中,TCP(Transmission Control Protocol,传输控制协议)是一个可靠的、面向连接的协议,它保证了数据包的顺序和完整性。为了建立一个稳定的连接,TCP 使用了一个被称为 三次握手(Three-W…

滑动窗口(1)_长度最小的子数组

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 滑动窗口(1)_长度最小的子数组 收录于专栏【经典算法练习】 本专栏旨在分享学习C的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. …

一款高效、简洁的帧动画生成工具

在现代网页设计和移动应用开发中,帧动画是一种常见的动画实现方式,它通过连续显示一系列静态图片来模拟动画效果。然而,手动创建和管理这些帧动画图片不仅耗时费力,而且效率低下。为此,gka 应运而生,它是一…

Java学习Day41:骑龙救!(springMVC)

springMVC与sevlet都是对应表现层web的,但是越复杂的项目使用SpringMVC越方便 基于Java实现MVC模型的轻量级web框架 目标: 小案例: 1.导入依赖 spring-context: 提供 Spring 框架的核心功能,如依赖注入、事件发布和其他应用上…

利用分布式锁在ASP.NET Core中实现防抖

前言 在 Web 应用开发过程中,防抖(Debounce) 是确保同一操作在短时间内不会被重复触发的一种有效手段。常见的场景包括防止用户在短时间内重复提交表单,或者避免多次点击按钮导致后台服务执行多次相同的操作。无论在单机环境中&a…

人工智能如何改变我们的工作方式

最近,我突然发现,人工智能正在悄悄地改变我们每天的工作方式。可能你和我一样,一开始并没怎么注意到这些变化,直到有一天,我才恍然大悟——原来我们已经不知不觉中被AI“包围”了!它正在一点一点地改变着我…

无人机之伯努利定律

无人机的伯努利定律是解释无人机飞行原理的关键理论之一,它主要阐述了流体(如空气)在流动过程中速度与压力之间的关系。以下是对无人机伯努利定律的详细解释: 一、伯努利定律的基本原理 伯努利定律是流体力学中的一个基本原理&am…

JavaScript知识点1

目录 1.JavaScript中常用的数组方法有哪些? 2.JavaScript的同源策略? 3.JavaScript中的 NaN 是什么? 4.JavaScript中的split、slice、splice函数区别? 1.JavaScript中常用的数组方法有哪些? 在 JavaScript 中&…

NEEP-EN2-2020-Text4

英二-2020-Text 4 摘自新闻周刊《Newsweek》2019年6月的文章《Gen Zs are Anxious, Entrepreneurial and Determined to Avoid Their Predecessor’s Mistakes》。 以下为个人解析,非官方公开标准资料,可能有误,仅供参考。(单词解…

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件 本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用r…

Word 脚注与正文之间的空行怎么删除啊?

全网都搜索不到解决方案,难道只有我一个人遇到这个问题了吗? 无语,。、;

Java导入、导出excel保姆级教程(附封装好的工具类)

前言 我们在日常开发中,一定遇到过要将数据导出为Excel的需求,那么怎么做呢?在做之前,我们需要思考下Excel的组成。Excel是由四个元素组成的分别是:WorkBook(工作簿)、Sheet(工作表)、Row(行)、Cell(单元格)&#xff…

Python中如何实现列表的排序

在Python中,实现列表(List)的排序是一项基础且常用的操作。Python提供了多种方式来对列表进行排序,包括使用内置函数、方法以及自定义排序逻辑。下面将详细探讨Python中实现列表排序的多种方法,包括sort()方法、sorted…

linux入门到实操-1 Linux概述、诞生过程、发行版本,如何安装?

教程来源:B站视频BV1WY4y1H7d3 3天搞定Linux,1天搞定Shell,清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料,供大家学习交流下载:夸克网盘分享 本文内容为完整笔记的入门篇 概述部分历史内容…

使用LSTM(长短期记忆网络)模型预测股票价格的实例分析

一:LSTM与RNN的区别 LSTM(Long Short-Term Memory)是一种特殊的循环神经网络(RNN)架构。LSTM是为了解决传统RNN在处理长序列数据时遇到的梯度消失或梯度爆炸问题而设计的。 在传统的RNN中,信息通过隐藏状…

linux-用户与权限管理-组管理

在 Linux 系统中,用户、组与权限管理是保障系统安全的重要机制。用户和组的管理不仅涉及对系统资源的访问控制,还用于权限的分配和共享。组管理在 Linux 中尤其重要,它能够帮助管理员组织用户并为不同的组分配特定权限,从而控制用…

使用虚拟信用卡WildCard轻松订阅POE:全面解析平台功能与订阅方式

POE(Platform of Engagement)是一个由Quora推出的人工智能聊天平台,汇集了多个强大的AI聊天机器人,如GPT-4、Claude、Sage等。POE提供了一个简洁、统一的界面,让用户能够便捷地与不同的AI聊天模型进行互动。这种平台的…