<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RogueYBJ</title>
    <description>The latest articles on DEV Community by RogueYBJ (@rogueybj).</description>
    <link>https://dev.to/rogueybj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3286720%2F8d7360b4-8bce-454c-bb16-80f425947364.jpeg</url>
      <title>DEV Community: RogueYBJ</title>
      <link>https://dev.to/rogueybj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rogueybj"/>
    <language>en</language>
    <item>
      <title>Harmony-Free WeChat Open Platform (WeChat Official Account Platform)</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:16:59 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-wechat-open-platform-wechat-official-account-platform-ai3</link>
      <guid>https://dev.to/rogueybj/harmony-free-wechat-open-platform-wechat-official-account-platform-ai3</guid>
      <description>&lt;p&gt;Hello, dear students! Good morning!&lt;br&gt;
Today, we are going to talk about the third-party libraries of the WeChat Open Platform.&lt;br&gt;
I believe that many of you have encountered various problems during the development process.&lt;br&gt;
Today, I will help you all clear up the problems with the WeChat third-party platform SDK.&lt;/p&gt;

&lt;p&gt;一、First, according to the requirements of the &lt;a href="https://developers.weixin.qq.com/doc/oplatform/Mobile_App/guideline/create.html" rel="noopener noreferrer"&gt;WeChat Open Platform&lt;/a&gt;, create the configuration for your own HarmonyOS application.&lt;/p&gt;

&lt;p&gt;二、Secondly, when using the SDK of third-party platforms, we must first import the third-party libraries. &lt;/p&gt;

&lt;p&gt;1、The method of introducing third-party libraries in WeChat&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @tencent/wechat_open_sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4arybexwltu30ap21zr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4arybexwltu30ap21zr8.png" width="528" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2、Check if WeChat is installed, and then add the following declaration in module.json5 "weixin""wxopensdk"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhoiuavre4brnyvmaj6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhoiuavre4brnyvmaj6x.png" width="325" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3、Configuration and the action agreed upon with WeChat: &lt;strong&gt;wxentity.action.open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2ae5p4m607bcpj4lfi6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2ae5p4m607bcpj4lfi6.png" width="427" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;三、Implement the related functions of WeChat&lt;/p&gt;

&lt;p&gt;1、Initialization (requires WeChat app ID)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// WeChat ID 
private wxId: string = "wxXXXXXXXXXappid";
// Instantiate the WeChat object 
private wx: WXApi = WXAPIFactory.createWXAPI(this.wxId)
// Application Context
private context: common.UIAbilityContext = getContext() as common.UIAbilityContext;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、WeChat message monitoring&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Initialization 
this.wx.handleWant(appWant, WXShareEventHandler)
// Register the Resp event WXShareEventHandler.registerOnWXRespCallback(handler.onResp)
// Cancel Resp event WXShareEventHandler.unregisterOnWXRespCallback(handler.onResp)
// Registration Request Event WXShareEventHandler.registerOnWXReqCallback(handler.onReq)
// Logout Req event
WXShareEventHandler.unregisterOnWXReqCallback(handler.onReq)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the listening code file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { BaseReq, BaseResp, Log, WXApiEventHandler } from "@tencent/wechat_open_sdk"

const kTag = "SharePluginWXApiEventHandlerImpl"

export type OnWXReq = (req: BaseReq) =&amp;gt; void

export type OnWXResp = (resp: BaseResp) =&amp;gt; void

class WXApiEventHandlerImpl implements WXApiEventHandler {
  private onReqCallbacks: Map&amp;lt;OnWXReq, OnWXReq&amp;gt; = new Map
  private onRespCallbacks: Map&amp;lt;OnWXResp, OnWXResp&amp;gt; = new Map

  registerOnWXReqCallback(on: OnWXReq) {
    this.onReqCallbacks.set(on, on)
  }
  unregisterOnWXReqCallback(on: OnWXReq) {
    this.onReqCallbacks.delete(on)
  }

  registerOnWXRespCallback(on: OnWXResp) {
    this.onRespCallbacks.set(on, on)
  }
  unregisterOnWXRespCallback(on: OnWXResp) {
    this.onRespCallbacks.delete(on)
  }

  onReq(req: BaseReq): void {
    Log.i(kTag, "onReq:%s", JSON.stringify(req))
    this.onReqCallbacks.forEach((on) =&amp;gt; {
      on(req)
    })
  }

  onResp(resp: BaseResp): void {
    Log.i(kTag, "onResp:%s", JSON.stringify(resp))
    this.onRespCallbacks.forEach((on) =&amp;gt; {
      on(resp)
    })
  }
}
export const WXShareEventHandler = new WXApiEventHandlerImpl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、WeChat Sharing &lt;/p&gt;

&lt;p&gt;Key point: Package the shared fixed elements into the "shareType" method &lt;/p&gt;

&lt;p&gt;Parameter 1: shareType - Sharing Type &lt;/p&gt;

&lt;p&gt;0: SendMessageToWXReq.WXSceneSession (Friend) &lt;/p&gt;

&lt;p&gt;SendMessageToWXReq.WXSceneTimeline (Friend Circle)&lt;/p&gt;

&lt;p&gt;Parameter 2: object: Sharing object &lt;/p&gt;

&lt;p&gt;textObject: Sharing Content Object &lt;/p&gt;

&lt;p&gt;imageObject: Sharing Image Object &lt;/p&gt;

&lt;p&gt;webpageObject: Webpage Sharing Object &lt;/p&gt;

&lt;p&gt;miniProgramObject: Mini Program Sharing Object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shareType(shareType:number,object:WXMediaMessage,handler?:HandlerAction):SendReqResultWrap{
    let req = new SendMessageToWXReq()
    req.scene = shareType

    let mediaMessage = new WXMediaMessage()
    mediaMessage.mediaObject = object
    mediaMessage.title = message.title
    mediaMessage.description = message.description

    req.message = message

    this.wx.sendReq(this.context,req)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copywriting Share&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const textObject = new WXTextObject()
textObject.text = args
this.shareType(0,textObject)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image sharing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const imageObject = new WXImageObject()
imageObject.uri = fileUri.getUriFromPath("file://path");
this.shareType(0,imageObject)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Webpage sharing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const webpageObject = new WXWebpageObject("https://xxxxxxx")
webpageObject.webpageUrl = args
this.shareType(0,webpageObject)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mini-program sharing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const miniProgramObject = new WXMiniProgramObject()
miniProgramObject.userName = "username"
miniProgramObject.path = "path"
this.shareType(0,miniProgramObject)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4、Launch the WeChat mini-program from the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const req = new LaunchMiniProgramReq()
req.userName = "username"
req.path = "path"
this.wx.sendReq(this.context,req)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5、Tap to open WeChat&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let ctx = getContext(this) as common.UIAbilityContext
let want:Want = {
    uri:"uri",
    action: "ohos.want.action.viewData"
}
ctx.startAbility(want);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to the &lt;a href="https://ohpm.openharmony.cn/" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;. Please use the following command to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/wechat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Share Content
WeChat.install.shareText("text",{onResp:(resp)=&amp;gt;{}})
// Share the picture
WeChat.install.shareImage("https://xxx",{onResp:(resp)=&amp;gt;{}})
// Share the webpage
WeChat.install.shareWeb("https://xxx",{onResp:(resp)=&amp;gt;{}})
// Share Mini Program
WeChat.install.shareMini({username:"username",path:"path"},{onResp:(resp)=&amp;gt;{}})
// Open the WeChat mini-program
WeChat.install.openMini({username:"username",path:"path"},{onResp:(resp)=&amp;gt;{}})
// Open WeChat
WeChat.install.openWX("uri",{onResp:(resp)=&amp;gt;{}})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong Dialog Customized Pop-up Window</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:10:24 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-dialog-customized-pop-up-window-21jk</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-dialog-customized-pop-up-window-21jk</guid>
      <description>&lt;p&gt;Hello everyone, nice to meet you all! Today, we are going to talk about the custom dialog "openCustomDialog" in HONOR OS. I believe that many of you will need to use pop-up windows in your development process, and it should not be coupled with the page during use. Today, I will help you all analyze the usage of "openCustomDialog" in detail.&lt;/p&gt;

&lt;p&gt;一、First, let's analyze the settings for pop-up windows in Harmony OS. Harmony OS provides some basic design for pop-up windows, but it cannot meet the requirements for diverse designs of pop-ups. However, it offers the method "openCustomDialog" which can be used. This method is based on the "PromptAction" under the UIContext.&lt;/p&gt;

&lt;p&gt;1、First, define a context&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Applying Context
private context: common.UIAbilityContext = getContext() as common.UIAbilityContext;
// Tips for Methodology
private promptAction: PromptAction = context.windowStage.getMainWindowSync().getUIContext().getPromptAction()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Let's take a look at the parameters of penCustomDialog. dialogContent refers to the content to be displayed, which is the component. options are the parameters related to the pop-up window, such as closing the pop-up window, etc. You can refer to the Harmony OS documentation for detailed descriptions. Here, we mainly discuss the custom components that need to be displayed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.promptAction().openCustomDialog(custom,options);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、The ComponentContent of the custom component has three parameters. Among them, the T type parameter is the key data for data interaction.&lt;/p&gt;

&lt;p&gt;uiContext: This is the context of the UI. getUIContext() &lt;/p&gt;

&lt;p&gt;builder: It is the WrappedBuilder&amp;lt;[T]&amp;gt; component decorated with &lt;a class="mentioned-user" href="https://dev.to/builder"&gt;@builder&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;args: is a parameter of type T&lt;/p&gt;

&lt;p&gt;1、"Builder" is a global component, which is the custom component we need to write. The generic type "T" represents the data object type that we need to pass, and "args" represents the data object that needs to be passed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// custom component
@Builder
export function customBuilder(params: DialogBuilderParams) {
    Text("custom component")
}
// create component
let custom = new ComponentContent(getUIContext(), wrapBuilder,params)
// show component
this.promptAction().openCustomDialog(custom,options);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、So, basically, this is the completion of a basic pop-up window. Next, let's talk about the parameters that the component needs to pass in. The parameters need to be displayed as 'params', and there are also the close method 'close' and other parameters 'status'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface DialogBuilderParams&amp;lt;T,R&amp;gt;{
  params: T
  close: (data: R) =&amp;gt; void
  status?: DialogStatus
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、After obtaining the data, it is displayed in the component. The code of the group definition component is modified. params.params is used to display the data, and params.close(true) is used to close the pop-up window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// custom component
@Builder
export function customBuilder(params: DialogBuilderParams) {
  Column() {
    Text(params.params).width('90%').textAlign(TextAlign.Center).padding(10)
    Blank()
    Divider()
    Text('确认')
      .onClick(() =&amp;gt; {
        params.close(true)
      })
      .width('100%')
      .aspectRatio(6)
      .textAlign(TextAlign.Center)
  }
  .width('70%')
  .backgroundColor(Color.White)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4、Implement the method for closing the popup window. When it is necessary to pass parameters for processing the close method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// create component
let custom = new ComponentContent(getUIContext(),wrapBuilder,{
    params: "This is the data to be presented.",
    close: (data: R) =&amp;gt; {
        // close dialog
        this.promptAction().closeCustomDialog(custom)
    }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to the &lt;a href="https://ohpm.openharmony.cn/#/cn/home" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;. Use the following command to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/dialog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Prompt Pop-up Window 
Dialog.alert({data:"alert"})
// Middle pop-up window 
Dialog.open({data:"open"})
// Bottom pop-up window 
Dialog.sheet({data:['sheet']})
// Selector Popup Window 
Dialog.picker({data:['picker']})
// Phone call pop-up window 
Dialog.tel("168********")
// Input box popup window 
Dialog.input({data:"input"})
// Time Selection Dialog Box 
Dialog.time({data:new Date()})
// Date selection dialog box 
Dialog.date({data:new Date()})
// Calendar Selection Dialog Box 
Dialog.calendar({data:new Date()})
// Custom Pop-up Window 
Dialog.custom(wrap, params)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong Generator Automatically Generates Modes</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:06:30 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-generator-automatically-generates-modes-3glc</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-generator-automatically-generates-modes-3glc</guid>
      <description>&lt;p&gt;Hello everyone, welcome! Today, we will be discussing the scenario of automatically generating models using JSON in Harmony. Many students often make mistakes when writing model data, either by omitting or miswriting certain parameters, or by incorrectly specifying the data type of the parameters. This can lead to unexpected errors during development, which require multiple debugging attempts to identify the problem. In this session, I will guide you all through using the hvigor script to implement the generator to automatically generate models, ensuring the correctness of the models.&lt;/p&gt;

&lt;p&gt;一、First, create a TypeScript project and import the necessary dependencies. You can refer to &lt;a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-hvigor-plugin" rel="noopener noreferrer"&gt;hvigor plugin development&lt;/a&gt; for details. Additionally, take a look at hvigor - it is a lightweight build tool provided by Huawei, which enables the automatic generation of models by writing JavaScript code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr55rr5g6kx2e5zfmdsxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr55rr5g6kx2e5zfmdsxf.png" width="501" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;二、The data in the JSON file is read from the specified path of the JSON data file using the hvigor and fs-extra plugins.&lt;/p&gt;

&lt;p&gt;1、Traverse and read the JSON file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;traverseDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dirent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;withFileTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;dirents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error reading directory &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;dirents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isDirectory&lt;/span&gt;&lt;span class="p"&gt;()){&lt;/span&gt;
                &lt;span class="c1"&gt;// If it is a folder, make a recursive call&lt;/span&gt;
                &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;traverseDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Read the file data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;traverseDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentPath&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;三、Create the model file using the fs-extra plugin and output it to the "out" folder. Create the model file based on the JSON file. Convert the JSON data into model data using jsonToModel, and then write it into the model file. &lt;/p&gt;

&lt;p&gt;1、Convert JSON data to model data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;jsonToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`\tconstructor(face:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Face) {\n\t\tif(face==null)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`\t&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;:Array&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt; | undefined \n`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;objName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`\t&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Model | undefined \n`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`\t&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; | undefined \n`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`\t\tthis.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; = face.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; \n`&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`export interface &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Face{ \n &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}\n\n`&lt;/span&gt;
    &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`export class &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Model implements &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Face{\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n}\n\n`&lt;/span&gt;
    &lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jsonToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Handling array nesting issues&lt;/span&gt;
&lt;span class="nf"&gt;arrayToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Array&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;objName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;otherMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;objName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Model&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Based on creating the model file and writing the model data into the model file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;traverseDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentPath&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.g.ets`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jsonToModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to &lt;a href="https://gitee.com/harmony-free/generator" rel="noopener noreferrer"&gt;Code Repository&lt;/a&gt;，Go to &lt;a href="https://gitee.com/harmony-free/generator/tree/master/lib" rel="noopener noreferrer"&gt;Download.tgz package&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1、Manual Import: Place the downloaded.tgz package into the project. In the &lt;code&gt;/hvigor/hvigor-config.json5&lt;/code&gt; file, introduce &lt;code&gt;XXX&lt;/code&gt; to replace the storage path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/hvigor/hvigor-config.json5

{
  "dependencies": {
    "@free/generator": "file:../XXX.tgz"
  },
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Introduce the hvigorfile.json5 file under the "entry" directory.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/entry/hvigorfile.json5

import { jsonToModelPlugin } from '@free/generator';

// Input: The location for JSON input. Default: /entry/json/
// Output: The location for the model. Default: /entry/model/

export default {
    system: hapTasks, 
    plugins:[
        jsonToModelPlugin(input?:string,out?:string)
    ]        
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、Execute the command &lt;code&gt;hvigorw --sync&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tbu2umu24j7z9xes6sk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tbu2umu24j7z9xes6sk.png" width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong List Refresh Loading Function</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:02:57 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-list-refresh-loading-function-12j</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-list-refresh-loading-function-12j</guid>
      <description>&lt;p&gt;Hello everyone, welcome! Today, we are going to talk about the refresh loading function in HarmonyOS. Refresh is mainly divided into two parts: pull-down refresh and pull-up load. By pulling up or down, we distinguish the refresh or loading status, and execute the current state's animation after releasing.&lt;/p&gt;

&lt;p&gt;一、First, obtain the sliding gesture, and then distinguish the sliding state by obtaining the position of the sliding movement.&lt;/p&gt;

&lt;p&gt;1、Obtain the sliding gesture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Define the 'refresh' extension attribute and pass in the RefreshUtils utility class to calculate the current status
// The 'List' can be used for any component
@Extend(List)
function refresh(refresh: RefreshUtils) {
  .offset({ x: 0, y: refresh.offsetY }) // The position of the sliding action
.onTouch((e) =&amp;gt; refresh.onTouch(e)) // Touch gesture
.enabled(refresh.state &amp;lt; 4) // Disables further sliding during the refreshing or loading process
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Calculate the current state based on the position obtained through.onTouch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export enum RefreshState {
  // Default state 
  normal,
// Currently in sliding state 
  runAll,
  // Currently in the process of loading more content by pulling up 
  runLoading,
  // Currently in the pull-to-refresh state 
  runRefresh,
  // Prepare for the pull-up loading state 
  readLoading,
  // Prepare for the pull-down refresh state 
  readRefresh,
  // Start loading 
  onLoading,
  // Start refreshing 
  onRefresh,
  // Success loading status 
  successLoading,
  // Loading failure state 
  failLoading,
  // Refresh successful status 
  successRefresh,
  // Failure in refreshing state 
  failRefresh,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、Based on the RefreshState status, customize the pull-to-load attempt and the pull-to-refresh attempt in the refreshBuilder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder
export function refreshBuilder(refresh: RefreshUtils) {
  if (refresh.isRefresh() &amp;amp;&amp;amp; refresh.upData != undefined) {
    Row() {
      if (refresh.state == RefreshState.runRefresh) {
        Text("↓").fontSize(25)
      } else if (refresh.state == RefreshState.readRefresh) {
        Text("↑").fontSize(25)
      } else if (refresh.state == RefreshState.onRefresh) {
        Text() {
          SymbolSpan($r('sys.symbol.rays'))
        }.fontSize(25).rotate({ angle: refresh.animator.progress * 360 })
      } else {
        Text() {
          SymbolSpan(refresh.state == RefreshState.successRefresh ? $r('sys.symbol.checkmark') :
          $r('sys.symbol.xmark'))
        }.fontSize(25)
      }
      Column() {
        if (refresh.state == RefreshState.runRefresh) {
          Text("Pull down to refresh").fontSize(14)
        } else if (refresh.state == RefreshState.readRefresh) {
          Text("Release to refresh immediately").fontSize(14)
        } else if (refresh.state == RefreshState.onRefresh) {
          Text("Refreshing...").fontSize(14)
        } else {
          Text(refresh.state == RefreshState.successRefresh ? "Refresh successful!" : "Refresh failed!").fontSize(14)
        }
        Text(`Last update:${refresh.refreshTiming.toLocaleTimeString()}`)
          .fontSize(12)
          .fontColor(0x999999)
          .padding({ top: 3 })
      }.padding({ left: 5 })
    }
    .height(50)
    .width('100%')
    .justifyContent(FlexAlign.Center)
    .position({ top: 0 })
  } else if (refresh.isLoading() &amp;amp;&amp;amp; refresh.downData != undefined) {
    Row() {
      if (refresh.state == RefreshState.runLoading) {
        Text("↑").fontSize(25)
      } else if (refresh.state == RefreshState.readLoading) {
        Text("↓").fontSize(25)
      } else if (refresh.state == RefreshState.onLoading) {
        Text() {
          SymbolSpan($r('sys.symbol.rays'))
        }.fontSize(25).rotate({ angle: refresh.animator.progress * 360 })
      } else {
        Text() {
          SymbolSpan(refresh.state == RefreshState.successLoading ? $r('sys.symbol.checkmark') :
          $r('sys.symbol.xmark'))
        }.fontSize(25)
      }
      Column() {
        if (refresh.state == RefreshState.runLoading) {
          Text("Pull up to load").fontSize(14)
        } else if (refresh.state == RefreshState.readLoading) {
          Text("Release and immediately load").fontSize(14)
        } else if (refresh.state == RefreshState.onLoading) {
          Text("Loading...").fontSize(14)
        } else {
          Text(refresh.state == RefreshState.successLoading ? "Loading completed!" : "Failed to load!").fontSize(14)
        }
        Text(`Last time loading:${refresh.loadingTiming.toLocaleTimeString()}`)
          .fontSize(12)
          .fontColor(0x999999)
          .padding({ top: 3 })
      }.padding({ left: 5 })
    }
    .height(50)
    .width('100%')
    .justifyContent(FlexAlign.Center)
    .position({ bottom: 0 })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to the &lt;a href="https://ohpm.openharmony.cn/" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;. Please use the following command to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
export struct RefreshComponent{

  @Builder
  itemBuilder(model:object){
    Text("item")
  }

/**
   * Refresh
   */
  upData = (page?: PageFace):Promise&amp;lt;boolean | Array&amp;lt;object&amp;gt;&amp;gt; =&amp;gt; {
    return new Promise&amp;lt;boolean | Array&amp;lt;object&amp;gt;&amp;gt;((res, rej) =&amp;gt; {
      res([])
    })
  }
  /**
   * Loading...
   */
  downData = (page?: PageFace):Promise&amp;lt;boolean | Array&amp;lt;object&amp;gt;&amp;gt; =&amp;gt; {
    return new Promise&amp;lt;boolean | Array&amp;lt;object&amp;gt;&amp;gt;((res, rej) =&amp;gt; {
      res([])
    })
  }

  build() {
    Column(){
      RefreshList({
        cachedCount:5,
        refresh:new RefreshUtils({upData:this.upData,downData:this.downData}),
        itemBuilderParam:this.itemBuilder,
      }).height("100%")
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong Network Network Library</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 08:55:45 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-network-network-library-28g8</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-network-network-library-28g8</guid>
      <description>&lt;p&gt;Hello everyone, nice to meet you all! Today, we are going to talk about the HTTP data request function of the network in HarmonyOS. During the daily development process, the interaction between the app and the server is inevitable. Network requests are also a crucial part of app development and one of the most frequently used tasks in app development.&lt;/p&gt;

&lt;p&gt;一、HTTP network requests consist of two crucial parts: the request parameters (options) and the response data (response).&lt;/p&gt;

&lt;p&gt;1、The request parameters &lt;strong&gt;options&lt;/strong&gt; contain several important parameters such as &lt;strong&gt;RequestMethod&lt;/strong&gt;, &lt;strong&gt;header&lt;/strong&gt;, and &lt;strong&gt;body&lt;/strong&gt;, and these parameters are encapsulated.&lt;/p&gt;

&lt;p&gt;1.1、The &lt;strong&gt;RequestMethod&lt;/strong&gt; includes &lt;strong&gt;OPTIONS&lt;/strong&gt;, &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;HEAD&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt;, &lt;strong&gt;DELETE&lt;/strong&gt;, &lt;strong&gt;TRACE&lt;/strong&gt;, and &lt;strong&gt;CONNECT&lt;/strong&gt;, among which the most commonly used ones are &lt;strong&gt;POST&lt;/strong&gt; and &lt;strong&gt;GET&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options.method == http.RequestMethod.GET
options.method == http.RequestMethod.POST
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.2、The &lt;strong&gt;header&lt;/strong&gt; of the request usually includes the verification signature &lt;strong&gt;token&lt;/strong&gt; required by the server as well as the data type &lt;strong&gt;Content-Type&lt;/strong&gt;, among other things.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HttpBase.baseHeader.set("Content-Type",this.contentType);
HttpBase.baseHeader.set("token",token);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.3、The &lt;strong&gt;body&lt;/strong&gt; of the request typically contains the data required by the server. &lt;strong&gt;options.extraData&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options.extraData = "data"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.4、The basic method for the request parameter &lt;strong&gt;options&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request(url:string,options:http.HttpRequestOptions){
    this.baseHeader.set("Content-Type",this.contentType);
    options.header = assign({},this.baseHeader,options.header??{})
    return this.httpRequest.request(url,options);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、The response parameter &lt;strong&gt;response&lt;/strong&gt; contains several important parameters such as &lt;strong&gt;responseCode&lt;/strong&gt;, &lt;strong&gt;result&lt;/strong&gt;, and &lt;strong&gt;resultType&lt;/strong&gt;, and these parameters are encapsulated.&lt;/p&gt;

&lt;p&gt;2.1、&lt;strong&gt;responseCode&lt;/strong&gt; - Response data status code. A status code of 200 indicates a successful response.&lt;/p&gt;

&lt;p&gt;2.2、&lt;strong&gt;Result&lt;/strong&gt; The corresponding data will have the data transmitted by the server when the status code is 200.&lt;/p&gt;

&lt;p&gt;2.3、The response data types of &lt;strong&gt;resultType&lt;/strong&gt; are &lt;strong&gt;STRING&lt;/strong&gt;, &lt;strong&gt;OBJECT&lt;/strong&gt;, and &lt;strong&gt;ARRAY_BUFFER&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;2.4 Response data acquisition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request(url:string,options:http.HttpRequestOptions){
    this.baseHeader.set("Content-Type",this.contentType);
    options.header = assign({},this.baseHeader,options.header??{})
    return this.httpRequest.request(url,options,(err,data)=&amp;gt;{
        if (err) {
          rej(err)
        }else{
          if (data.responseCode == 200) {
            res(data)
          }else{
            rej(JSON.stringify(data.result))
          }
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、Process the response data. While obtaining the data, it is also desired to perform some processing, and it is hoped that the data can be transformed into the form of a model for direct use.&lt;/p&gt;

&lt;p&gt;1、Specify the type you want to obtain by passing in different T generics. The default generics are &lt;strong&gt;object | string | ArrayBuffer&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request&amp;lt;T = object | string | ArrayBuffer&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、Process the incoming T generic type and return the corresponding model type HttpResp&amp;lt; T &amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request&amp;lt;T = object | string | ArrayBuffer&amp;gt;(url:string,options:http.HttpRequestOptions): Promise&amp;lt;HttpResp&amp;lt;T&amp;gt;&amp;gt; {
    return new Promise((res,rej)=&amp;gt;{
      this.httpRequest.request(url,options,(err,data)=&amp;gt;{
        if (err) {
          rej(err)
        }else{
          if (data.responseCode == 200) {
            let resp:HttpResp&amp;lt;T&amp;gt; = {
              responseCode: data.responseCode,
              code: data.responseCode,
              msg: "Request successful",
              data: data.result as T,
            }
            res(resp)
          }else{
            rej(JSON.stringify(data.result))
          }
        }
        this.finish()
      })
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to the &lt;a href="https://ohpm.openharmony.cn/" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;. Please use the following command to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// GET request
Http.get&amp;lt;object&amp;gt;("url",new Map());
// POST request
Http.post&amp;lt;object&amp;gt;("url",new Map());
// Download Request
Http.download&amp;lt;string&amp;gt;("url");
// Uploading image request
Http.upImage&amp;lt;string&amp;gt;("url",{image:"file"});
// Get request for uploading multiple images
Http.upImages("url",[{image:"file"}]);
// Perform multiple asynchronous requests
Http.requests({url:"url1"},{url:"url2",resp:(resp)=&amp;gt;{}});
// Perform synchronous execution of multiple requests
Http.requestsAsync({url:"url1"},{url:"url2",resp:(resp)=&amp;gt;{}});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong Loading Frame</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 08:49:09 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-loading-frame-560j</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-loading-frame-560j</guid>
      <description>&lt;p&gt;Hello, dear students! Good morning! Today, we are going to talk about the commonly used loading box function in HONAM. It is developed based on the Overlay layer. During the development process, the loading box can be seen everywhere. Whenever there is an asynchronous operation with a delay involved, it needs to be displayed to prevent the page from being unresponsive and causing a poor user experience.&lt;/p&gt;

&lt;p&gt;一、Understand Overlay. Overlay is a layer of covering on top of getUIContext.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let context = getContext() as common.UIAbilityContext
let overlay = context.windowStage.getMainWindowSync().getUIContext().getOverlayManager()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、Add, delete, display, and hide overlay components&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add overlay component
overlay.addComponentContent(content)
// Remove the overlay component
overlay.removeComponentContent(content)
// Display the overlay component
overlay.showComponentContent(content)
// Hidden Overlay Component
overlay.hideComponentContent(content)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;三、Create component、Update the data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create component
let content = new ComponentContent(this.getUIContext(), builder, args)
// Update the data
content.update(args)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;四、Custom builder component, with six states: loading, success, failure, info, warn, and progress.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
export enum LoadingState {
  loading = 'sys.symbol.loading',
  success = 'sys.symbol.checkmark',
  failure = 'sys.symbol.xmark',
  info = 'sys.symbol.info_circle',
  warn = 'sys.symbol.exclamationmark_circle',
  progress = 'sys.symbol.progress'
}

export interface LoadingParamFace {
  state?: LoadingState
  msg: string
  progress?: number
  progressColor?: number | string
  total?: number
  data?: object
}

@Builder
function loadingCustom(param: LoadingParamFace) {
  Column() {
    Column() {
      if (param.state ?? LoadingState.loading == LoadingState.loading) {
        LoadingProgress().width(50).height(50).color(0xFF444444)
      } else if (param.state == LoadingState.progress) {
        Progress({ value: param.progress, total: param.total, type: ProgressType.Ring })
          .width(50)
          .padding(5)
          .style({ strokeWidth: 3, enableScanEffect: true })
      } else {
        Text() {
          SymbolSpan($r(param.state))
        }.fontSize(40)
        .padding(5).fontColor(0xFF444444)
      }
      Text(param.msg ?? "Loading...").fontSize(14).fontColor(0xFF444444)
    }.backgroundColor(Color.White).padding(20).borderRadius(10)
  }.backgroundColor(0x30000000).justifyContent(FlexAlign.Center).height('100%').width('100%')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to the &lt;a href="https://ohpm.openharmony.cn/" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;. Please use the following command to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/loading
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Display the loading loading box Loading.show({state:LoadingState.loading})
// Hide the loading loading box 
Loading.hide()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Global Device Global Attributes</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 08:32:49 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-global-device-global-attributes-5a3b</link>
      <guid>https://dev.to/rogueybj/harmony-free-global-device-global-attributes-5a3b</guid>
      <description>&lt;p&gt;Hello, dear students! Good morning! Today, we are going to talk about the commonly used "global" attributes in HarmonyOS. During the development process, it is often necessary to obtain information related to the screen size (width and height), orientation (portrait or landscape), application-related information, packaging-related information, etc., which is all about app development.&lt;/p&gt;

&lt;p&gt;一、Screen Information Display &lt;a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-display-V5#displaygetdisplaybyidsync12" rel="noopener noreferrer"&gt;Detailed Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1、The width and height of the screen&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Screen-related information
let dis = display.getDefaultDisplaySync()
// Screen width 
this.width = px2vp(dis.width)
//  Screen height
this.height = px2vp(dis.height)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、The height occupied by the liuhai screen and the notch screen from top to bottom&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// The height occupied by the top of the screen
let top = this.main.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height
// The height occupied at the bottom of the screen
let bottom = this.main.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height
// px Conversion vp
top = px2vp(top)
bottom = px2vp(bottom)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、The width and height of the screen content as well as the height of the selection bar in the navigation bar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Screen width
let contextWidth = width
// Screen height
let contextHeight = height - bottom - top
// Navigation bar height
let navBarHeight = top + 44;
// Height of the selection bar
let tabBarHeight = bottom + 49 + 10;
// Content Height
let contentHeight = height - navBarHeight - tabBarHeight
// Content height plus navigation bar height
let contentNavBar = height - tabBarHeight
// Content height plus navigation bar height
let contentTabBar = height - navBarHeight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、Application-related information &lt;a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-bundlemanager-applicationinfo-V5" rel="noopener noreferrer"&gt;Detailed document&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Application-related Information
let appInfo = bundleManager.getBundleInfoForSelfSync(flags).appInfo
// Application package name
appInfo.name
// Application Name
appInfo.label
// Application Environment
appInfo.appProvisionType
// Packaging environment
appInfo.releaseType
// tokenId
appInfo.accessTokenId

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;三、Package the relevant information &lt;a href="https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-bundlemanager-bundleinfo-V5" rel="noopener noreferrer"&gt;Detailed Document&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Packaging information
bundleInfo = bundleManager.getBundleInfoForSelfSync(flags)
// Version number
bundleInfo.versionName
// Signature information
bundleInfo.signatureInfo
// 安装时间
bundleInfo.installTime
// Author
bundleInfo.vendor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to &lt;a href="https://ohpm.openharmony.cn/#/cn/home" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;,Use the following command to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/global
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Screen-related information, etc....
global.top
global.bottom
global.width
global.height
global.getNavBarHeight()
global.getTabBarHeight()
global.getContentHeight()
global.getContentNavBar()
global.getContentTabBar()
// Apply relevant information, etc....
global.appInfo
global.appName
global.bundleName
global.env
global.releaseType
global.release
global.debug
global.tokenId
// Package the relevant information...
global.bundleInfo
global.bundleInfo.signatureInfo
global.bundleInfo.installTime
global.bundleInfo.vendor
global.bundleInfo.name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Navigation Container Navigation</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 08:24:40 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-navigation-container-navigation-4411</link>
      <guid>https://dev.to/rogueybj/harmony-free-navigation-container-navigation-4411</guid>
      <description>&lt;p&gt;Hello, dear students! Good morning! Today, we are going to talk about the Navigation container navigation component commonly used in HONOR. During the development process, page navigation is quite common. Generally, an application has dozens or even hundreds of pages, so controlling page navigation is of utmost importance.&lt;/p&gt;

&lt;p&gt;一、First, it is necessary to understand the composition of the Navigation container navigation component. NavPathStack and NavDestination are the core components, along with a core attribute: navDestination(). The official documentation is quite elaborate, but the essence of it boils down to these three elements.&lt;/p&gt;

&lt;p&gt;1、The Navigation component is the main page component. Add this component to the @Entry page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entry
@Component
struct Index {
    build() {
        Navigation(){

        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、NavPathStack is the key controller for managing page navigation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let navPathStack: NavPathStack = new NavPathStack();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、NNavDestination is the component being navigated. It is a custom component decorated with @Component and needs to be invoked through a global dispatch call decorated with &lt;a class="mentioned-user" href="https://dev.to/builder"&gt;@builder&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Builder
export function testBuilder(o:object){
  NavDestination(){
    TestPage()
  }
}

@Component
export struct TestPage{
  build() {
    Text("TestPage")
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4、The "navDestination()" attribute of the Navigation component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.navDestination((builderName: string, p: object) =&amp;gt; {
  if (builderName == "testBuilder") {
    return wrapBuilder(testBuilder).builder(p)
  }
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5、At this point, the entire page has reached a closed loop, and all the codes are listed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const navPathStack: NavPathStack = new NavPathStack();

@Entry
@Component
struct Index {
    build() {
        Navigation(navPathStack){
            Text("testPage").onClick(()=&amp;gt;{
                navPathStack.pushPathByName("testPage",new Map)
            })
        }.navDestination((builderName: string, p: object) =&amp;gt; {
            if (builderName == "testBuilder") {
            return wrapBuilder(testBuilder).builder(p)
            }
        })
    }
}

@Builder
export function testBuilder(o:object){
  NavDestination(){
    TestPage({o:o})
  }
}

@Component
export struct TestPage{
  o: object|undefined
  build() {
    Column(){
      Text("TestPage")
      Text("Go back to the previous page").onClick(()=&amp;gt;{
        navPathStack.pop()
      })
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Are you a little surprised? Why is it only so little, when there are so many documents? Yes! Exactly! The main core is just written like this, but to handle the daily cumbersome requirements, these codes need to be encapsulated!&lt;/p&gt;

&lt;p&gt;Note: The complete code has been submitted to &lt;a href="https://ohpm.openharmony.cn/#/cn/home" rel="noopener noreferrer"&gt;HarmonyOS Third-Party Library&lt;/a&gt;,Use the following command to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/navigation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method: After writing the sub-page as described above, you need to register the requestBuilder for the sub-page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Registration sub-page
nav.requestBuilder('path',wrapBuilder(testBuilder))
// Redirecting the page and receiving the returned parameters
nav.push("path",new Map).then((data)=&amp;gt;{
    if (data.data!=undefined) {
        // TODO: Handle the return parameters
    }
})
// Return to the page and pass the return parameter
nav.pop(new Map);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free: Hengong Preferences - Preferences Settings</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Tue, 24 Jun 2025 01:20:11 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-preferences-preferences-settings-24ko</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-preferences-preferences-settings-24ko</guid>
      <description>&lt;p&gt;Hello everyone, nice to meet you all! Today, we are going to talk about the preferences data storage commonly used in HarmonyOS. During the development process, we usually use some persistent data storage methods. Some user data and commonly used fixed data can all be stored using preferences.&lt;/p&gt;

&lt;p&gt;一、Let's have a brief look at the preferences data storage. Preferences use Key-Value key-value type for data storage, and data is stored and retrieved through the Key.&lt;/p&gt;

&lt;p&gt;1、preferences Create data storage instance instantiation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preferences = preferences.getPreferencesSync(getContext(), { name: 'base' });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、preferences Basic method，def As the default value，value For data values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Store data
preferences.put(key, value)
preferences.putSync(key, value)
// Obtain data
preferences.get(key, value)
preferences.getSync(key, def)
// Obtain all the data
preferences.getAll();
preferences.getAllSync();
// Delete data
preferences.delete(key)
preferences.deleteSync(key)
// Clear data
preferences.clear();
preferences.clearSync();
// Synchronize to the preferences library
preferences.flush();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3、After performing operations on the stored data, a flush synchronization is required. Therefore, it is possible to directly perform the flush operation after performing put, delete, and clear operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add or update and synchronize
putFlush(key: string, value: preferences.ValueType) {
    preferences.putSync(key, value)
    preferences.flush()
}
// Delete and synchronize
deleteFlush(key: string) {
    if (this.has(key)) {
        preferences.deleteSync(key)
        preferences.flush()
    }
}
// Clear and synchronize
clearFlush() {
    preferences.clearSync()
    preferences.flush()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4、Based on these, implement multi-value storage and multi-value retrieval&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Obtain multiple pieces of data
getForKeys(...keys: string[]): Map&amp;lt;string, preferences.ValueType&amp;gt; {
    let map: Map&amp;lt;string, preferences.ValueType&amp;gt; = new Map&amp;lt;string, preferences.ValueType&amp;gt;()
    keys.forEach((key) =&amp;gt; {
        let value = preferences.getSync(key)
        map.set(key, value)
    })
    return map
}
// Store multiple pieces of data
putMap(map: Map&amp;lt;string, preferences.ValueType&amp;gt;) {
    map.forEach((v, k) =&amp;gt; {
        preferences.putSync(k, v)
    })
}
// Store multiple pieces of data and synchronize them
putMapFlush(map: Map&amp;lt;string, preferences.ValueType&amp;gt;) {
    map.forEach((v, k) =&amp;gt; {
        preferences.putSync(k, v)
    })
    preferences.flush()
}
// Delete multiple pieces of data
deleteForKeys(...keys: string[]){
    keys.forEach((key) =&amp;gt; {
        this.delete(key)
    })
}
// Delete multiple pieces of data and synchronize.
deleteForKeysFlush(...keys: string[]){
    keys.forEach((key) =&amp;gt; {
        this.delete(key)
    })
    preferences.flush()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to&lt;a href="https://ohpm.openharmony.cn/#/cn/home" rel="noopener noreferrer"&gt;Hongmeng Tripartite Library&lt;/a&gt;,Use the following command to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/preferences
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling method: It is recommended to use the one with the "Flush" method as the default option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new PreferencesUtils().get("");
new PreferencesUtils().getForKeys("","","");
new PreferencesUtils().getAll();
new PreferencesUtils().getMap();
new PreferencesUtils().put("",0);
new PreferencesUtils().putFlush("",0);
new PreferencesUtils().putMap(new Map);
new PreferencesUtils().putMapFlush(new Map);
new PreferencesUtils().delete("");
new PreferencesUtils().deleteFlush("");
new PreferencesUtils().deleteForKeys("","","");
new PreferencesUtils().deleteForKeysFlush("","","");
new PreferencesUtils().clear()
new PreferencesUtils().clearFlush()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony-Free Hengong Log Console Outputs Logs</title>
      <dc:creator>RogueYBJ</dc:creator>
      <pubDate>Mon, 23 Jun 2025 08:57:09 +0000</pubDate>
      <link>https://dev.to/rogueybj/harmony-free-hengong-log-console-outputs-logs-121c</link>
      <guid>https://dev.to/rogueybj/harmony-free-hengong-log-console-outputs-logs-121c</guid>
      <description>&lt;p&gt;Hello everyone, welcome! Today, we will talk about the commonly used log logging in HarmonyOS. During the development process, logging is basically indispensable. Logging can help us quickly locate and identify problems. However, sometimes during the development process, the testers who show the bugs on their phones cannot directly locate the problems even when the developers are present. It would be great if the console logging could be displayed on the phone, right? Today, we will discuss how to use the AOP aspect capabilities provided by the Aspect tool class to implement monitoring and logging, as well as how to open the console log output page by shaking the phone.&lt;/p&gt;

&lt;p&gt;一、Monitor and print logs through the AOP aspect capabilities of the Aspect tool class&lt;/p&gt;

&lt;p&gt;1、Add the "logAfter" monitoring method to the &lt;strong&gt;log&lt;/strong&gt; printing method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;util.Aspect.addAfter(console, 'log', true, this.logAfter)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2、The &lt;strong&gt;logAfter&lt;/strong&gt; monitoring method records the log entries into the &lt;strong&gt;logList&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logAfter: (instance: console, method: string, arg: string, ...args: object[]) =&amp;gt; void  = (instance: console, method: string, arg: string, ...args: object[]) =&amp;gt; {
      let msg = arg
      if (args != undefined) {
        args.forEach((a) =&amp;gt; {
          msg += JSON.stringify(a)
        })
      }
      this.logList.push(new LogModel(msg))
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;二、Open the console output log page by shaking the mobile phone.&lt;/p&gt;

&lt;p&gt;1、Configure the permissions for the mobile phone sensors&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pdku2mntiu478vin758.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pdku2mntiu478vin758.png" width="652" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2、Monitor the mobile phone sensors and open the console output log page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sensors = sensor.getSensorListSync()
// Start listening
open() {
    if (this.findSensor(sensor.SensorId.ACCELEROMETER)){
      try {
        sensor.on(sensor.SensorId.ACCELEROMETER, this.action.bind(this));
      } catch (error) {
        let e: BusinessError = error as BusinessError;
        console.error(`Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
      }
    }else{
      console.error(`not find id with ${sensor.SensorId.ACCELEROMETER}`);
    }
}
// Turn off the listening function
close(){
    try {
      sensor.off(sensor.SensorId.ACCELEROMETER, this.action.bind(this));
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(`Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
    }
}
// Open the console log page
action(data: sensor.GyroscopeResponse){
    if ((data.x &amp;gt; this.num || data.y &amp;gt; this.num || data.z &amp;gt; this.num) &amp;amp;&amp;amp; (this.isOn)) {
      this.isOn = false
      if (this.type === "router"){
        router.pushNamedRoute({name:"log"})
      }else {
        nav.push("log").then(() =&amp;gt; {
          this.isOn = true
        })
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The complete code has been submitted to&lt;a href="https://ohpm.openharmony.cn/#/cn/home" rel="noopener noreferrer"&gt;Hongmeng Tripartite Library&lt;/a&gt;,Use the following command to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohpm install @free/log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The calling method: The onCreate and onDestroy methods in the EntryAbility class respectively invoke the following two methods&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Start log monitoring
Log.open()
// Disable log monitoring
Log.close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you like this content, please give a little heart!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
