13

1. What is Hongmeng

Hongmeng is HarmonyOS. It is a distributed operating system launched by Huawei that supports multiple terminal devices such as mobile phones, tablets, smart wearables, smart screens, and car machines. It also provides APIs for multi-language development and supports Java, XML, C/ C++, JS, CSS, HML (Hongmeng's own markup language similar to HTML) and other development languages, and it provides a variety of responsive layout schemes, supports rasterized layout, and can be deployed on mobile phones, watches, tablets, etc. with the same set of codes On devices with different screen sizes.

2. Development preparation

2.1 Environmental installation

The development of Hongmeng software requires HUAWEI DevEco Studio, which provides services such as template creation, development, compilation, debugging, and release.

1. Log in to HarmonysOS application development portal , click the register button in the upper right corner to register a developer account.

2. Enter the HUAWEI DevEco Studio product page , log in to the Huawei developer account, download the DevEco Studio installation package and install it.

3. Start DevEco Studio and download the HarmonyOS SDK according to the tool guide.
下载HarmonyOS SDK

4. After successfully downloading the HarmonyOS SDK, you will enter the welcome page, click Configure> Settings in the welcome page to open the settings window, click Apparance&behavior> System settings> HarmonyOS SDK, and select JS SDK to download.
下载JS SDK

At this point, the development environment is installed.

2.2 New project

Click File> New> New Project in the menu bar
新建项目
Select the project equipment that needs to be developed, and then select Empty Featrue Ability(JS), click Next, and the information configuration of the project will appear at this time
项目信息配置
Click Finish, and a new project is created.

2.3 Project Directory

项目目录

If you use the JS SDK for development, you need to pay attention to the entry> src> main> js folder, where:

  • Multilingual json files are stored in the i18n directory

    en-US.json is the content displayed in English mode
    zh-CN.json is the content displayed in Chinese mode
  • Stored under pages are multiple pages of the project, each page is composed of hml, js and css

    The hml file defines the layout of the page, the components used in the page, and the hierarchical relationship of these components
    The js file defines the business logic of the page, such as data binding, event processing, etc.
    The css file defines the style of the index page
  • App.js stores the global js logic and app life cycle management

In addition, you can also create a common directory to store common resource files, such as: public styles and public methods.

2.4 Life cycle

The life cycle is divided into the life cycle of the application and the life cycle of the page

生命周期

Among them, the life cycle of an application is mainly divided into onCreate, which is called when the application is created, and onDestroy, which is triggered when the application is destroyed.

The life cycle of the page is divided into:

  • onInit: Triggered when the page data preparation is complete;
  • onReady: triggered when the page is compiled;
  • onShow: triggered when the page is displayed;
  • onHide: triggered when the page is hidden;
  • onDestroy: triggered when the page is destroyed;

Since JS UI only supports applications running at the same time and displaying one page, when the application jumps from page A to page B, it first triggers the onHide and onDestroy functions of page A, and then calls the onInit, onReady, and onShow functions of page B in turn to initialize And display page B.

Three, components

In the hml file, the components are divided into container components, basic components, media components, canvas components, and grid components. Due to limited space, only the component names and corresponding descriptions are listed here. Interested students can click component document proceed. Check it out.

3.1 Container components

Component namedescription
divBase container
listList container
list-itemThe sub-components of list, used to display the specific items of the list
list-item-groupThe sub-components of list, used to display groupings, the width is full of list components by default
badgeNew event tag container
dialogCustom pop-up container
panelPop-up sliding panel container
popupBubble reminder container
refreshPull down to refresh the container
stackStack the container, the sub-components are put into the stack in order, the next sub-component covers the previous one
stepperStep navigator. When multiple steps are required to complete a task, you can use the step navigator to show the current progress
stepper-itemStep navigator sub-component, as the content display component of a certain step of the step navigator
swiperSwipe to switch containers
tabstab switch container
tab-barSub-components of tabs, used to display the tab area of the tab
tab-contentSub-components of tabs, used to display the content area of the tab

3.2 Basic components

Component namedescription
imagePicture component, used to render and display pictures
image-animatorPicture frame animation player
textText component, used to display text information
spansub-component of text, providing text modification capabilities
textareaMulti-line text input box
inputInteractive components, including single-select boxes, multiple-select boxes, buttons and single-line text input boxes
buttonButton components, including capsule buttons, round buttons, text buttons, arc buttons, download buttons
chartChart component, used to present line graph, bar graph, gauge graph interface
dividerProvide a divider component to separate different content blocks/content elements. Can be used for list or interface layout
labelDefine corresponding annotations for the input, button, and textarea components. Clicking on the annotation will trigger the click effect of the bound component
marqueeMarquee component, used to display a single-line scrolling text
menuMenu component, as a temporary pop-up window, used to display the operations that the user can perform
selectDrop-down selection of components allows users to choose between multiple options
optionCan be used as a sub-component of the menu or select component to display specific items
pickerSliding selector component, the type supports normal selector, date selector, time selector, time and date selector, multi-column text selector
picker-viewSlide selector embedded in the page
pieceA blocky entrance component that can contain pictures and text, often used to show recipients
progressProgress bar component, used to display content loading or operation processing progress
qrcodeTwo-dimensional code component, used to generate and display two-dimensional code
ratingScore bar component
searchSearch box component, used to provide input area for users to search content
sliderSlider component, used to quickly adjust setting values, such as volume, brightness, etc.
switchSwitch components, used to turn on or off a function
toolbarToolbar component, placed at the bottom of the interface, used to display the operation options for the current interface
toolbar-itemtoolbar sub-component, used to display an operation option on the toolbar
toggleStatus button component, used to select from a set of options

3.3 Media components

The media component is temporarily only video component, except that smart wearable devices do not support this component, mobile phones, tablets, smart screen devices support this component, it provides the device with video playback function.

3.4 Canvas component

The canvas component shows only one canvas component, which is supported by mobile phones, tablets, smart screens, and smart wearable devices. It provides the device with the ability to customize graphics.

3.5 Grid components

Component namedescription
grid-containerGrid layout container root node
grid-rowgrid-row is a sub-container component of grid-container. It uses flex horizontal layout to arrange each grid-col container. Justify-content and align-items default to flex-start, and support line break display
grid-colSub-container component of grid-row

The grid system has three attributes: Margins, Gutters, and Columns:

  • Margins: used to control the distance of the element from the edge of the screen
  • Gutters: used to control the distance relationship between elements and elements
  • Columns: The main positioning tool used to assist the layout. Different screen sizes match different Columns numbers to assist the layout positioning. It will automatically calculate the width of each Columns according to the width of the actual device and the number of Columns.

栅格系统

Different devices display different numbers of grids according to the horizontal width px:

xs: 0px <horizontal resolution <320px: 2 Columns grid;

sm: 320px <= horizontal resolution <600px: 4 Columns grid;

md: 600px <= horizontal resolution <840px: 8 Columns grid;

lg: 840px <= horizontal resolution: 12 Columns grid.

Four, HML syntax

HML (HarmonyOS Markup Language) is a set of HTML-like markup language, which constructs the content of the page through components and events. The page has the capabilities of event binding, data binding, list rendering, conditional rendering, and logic control.

4.1 Event binding

The event binding in hml returns an event object parameter by default, through which event information can be obtained, and additional parameters can also be passed.

<!-- xxx.hml -->
<div>
  <!-- 正常格式 -->
  <div onclick="clickfunc"></div>
  <!-- 缩写 -->
  <div @click="clickfunc('hello')"></div>
  <!-- 使用事件冒泡模式绑定事件回调函数 -->
  <div on:touchstart.bubble="touchstartfunc"></div>
  <!-- 使用事件捕获模式绑定事件回调函数 -->
  <div on:touchstart.capture="touchstartfunc"></div>
  <!-- on:{event}等价于on:{event}.bubble -->
  <div on:touchstart="touchstartfunc"></div>
  <!-- 绑定事件回调函数,但阻止事件向上传递 -->
  <div grab:touchstart.bubble="touchstartfunc"></div>
  <!-- 绑定事件回调函数,但阻止事件向下传递 -->
  <div grab:touchstart.capture="touchstartfunc"></div>
  <!-- grab:{event}等价于grab:{event}.bubble -->
  <div grab:touchstart="touchstartfunc"></div>
</div>
// xxx.js
export default {
  data: {
    text: '',
  },
  clickfunc: function(str, e) {
    console.log(e);
    this.text = str;
  },
  touchstartfunc: function(e) {
    console.log(e);
  }
}

4.2 Data binding

There are two forms of data binding: data initialization, data update
数据更新流程

hml only supports one-way data binding from the data layer to the view layer.
If the view layer wants to change the data layer, it can only be achieved by binding events.

4.2.1 Data initialization

The data in hml comes from the data object in the corresponding js, so when you initialize the page, write data in the data object, and you can bind the data in the form of {{}} in hml.

// xxx.js
export default {
  data: {
    text: 'HELLO WORLD'
  }
}
<!-- xxx.hml -->
<div>{{text}}</div>

4.2.2 Data update

By binding events to page elements, methods can be called to update data, which triggers the view to update data

// xxx.js
export default {
  data: {
    text: 'HELLO WORLD'
  },
  changeText: function() {
    this.$set('text', '你好,世界');
  }
}
<!-- xxx.hml -->
<div @click='changeText'>{{text}}</div>

4.3 List rendering

If you need to perform list rendering in hml, you only need to add the for attribute on the component and bind the data that needs to be rendered. At the same time, you can customize the names of variables and indexes:

// xxx.js
export default {
  data: {
    array: [
      {id: 1, name: '老周', age: 28}, 
      {id: 2, name: '老李', age: 29},
    ],
  },
  changeText: function(val, index) {
    if (val === "老李"){
      this.array.splice(index, 1, {id:2, name: '老王', age: 30});
    } else {
      this.array.splice(index, 1, {id:3, name: '老郑', age: 31});
    }
  },
}
<!-- xxx.hml -->
<div class="array-container">
  <!-- div列表渲染 -->
  <!-- 默认$item代表数组中的元素, $idx代表数组中的元素索引 -->
  <div for="{{array}}" tid="id" onclick="changeText($item.name, $idx)">
    <text>{{$idx}}.{{$item.name}}</text>
  </div>
  <!-- 自定义元素变量名称 -->
  <div for="{{value in array}}" tid="id" onclick="changeText(value.name, $idx)">    
    <text>{{$idx}}.{{value.name}}</text>
  </div>
  <!-- 自定义元素变量、索引名称 -->
  <div for="{{(index, value) in array}}" tid="id" onclick="changeText(value.name, index)">    
    <text>{{index}}.{{value.name}}</text>
  </div>
</div>
Each element in the array must have the data attribute specified by tid, and it must be unique.
For data modification in the array, please use the splice method to validate the data binding changes

4.4 Conditional rendering

There are two ways to implement conditional rendering in hml. They are adding if/elif/else or show attributes to the component. The difference is that if/elif/else attributes do not meet the conditions, they will not be constructed in vdom, and the show attribute is Although it will not be rendered when false, it will be built in vdom, but the display style is set to none.

Therefore, for performance considerations, the display and hidden state needs to be switched frequently and it is recommended to use show. If the display state changes less frequently, use if/elif/else.

// xxx.js
export default {
  data: {
    show: false,
    display: true,
    visible: false
  },
  toggle: function() {
    this.visible = !this.visible;
  }
}
<!-- xxx.hml -->
<div class="container">
  <text if="{{show}}"> 你好,世界 </text>
  <text elif="{{display}}"> hi </text>
  <text else> Hello World </text>
  
  <button class="btn" type="capsule" value="toggle" onclick="toggle"></button>
  <text show="{{visible}}" > Hello World! </text>
</div>
When using the if/elif/else writing method, the node must be a sibling node, otherwise the compilation will not pass
It is forbidden to set the for and if attributes on the same element at the same time

4.5 Logic Control Block

The <block> control block is provided in hml, which will not be compiled as a real node, but only supports for and if attributes.

4.6 Custom components

HML can use the element tag to reference template files, which can be used to implement custom components.

<!-- template.hml -->
<div class="item"> 
  <text>Name: {{name}}</text>
  <text>Age: {{age}}</text>
</div>
<!-- index.hml -->
<element name='man' src='../../common/template.hml'></element>
<div>
  <man name="老朱" age="28"></man>
</div>

The name attribute of the element tag is the name of the custom component, and the src attribute is the path of the custom component relative to the file. You can add attributes to the custom component label to transfer data to it. You can also use the $emit method in the custom component to send data to the parent The component passes parameters.

Five, JS syntax

The js file in Hongmeng supports ES6 syntax.

5.1 Reference

In Hongmeng, you can use the import method to import functional modules or js code:

import router from '@system.router'
import utils from '../../common/utils.js'

5.2 Get app object

In the page, you can use this.$app.$def get the objects exposed in app.js.

// app.js
export default {
  onCreate() {
    console.info('App onCreate');
  },
  onDestroy() {
    console.info('App onDestroy');
  },
  globalData: {
    appData: 'appData',
    appVersion: '2.0',
  },
  changeAppVer () {
    this.globalData.appVersion = '3.0';
  }
};
// index.js
export default {
  data: {
    appData: 'localData',
    appVersion:'1.0',
  },
  onInit() {
    this.appData = this.$app.$def.globalData.appData;
    this.appVersion = this.$app.$def.globalData.appVersion;
  },
  pageMethod() {
    this.$app.$def.changeAppVer();
  }
}

5.3 Page Object

AttributesTypes ofdescription
dataObject/FunctionData model of the page
$refsObjectObjects that hold instances of DOM elements or child components that have registered ref attributes
propsArray/Objectprops is used to receive the parameters passed by the parent component
computedObjectCalculated attributes, used for pre-processing when reading or setting, the results of the calculated attributes will be cached
privateObjectThe data model of the page, the data attributes under private can only be modified by the current page
publicObjectThe data model of the page, the behavior of the data attributes under public is consistent with data

5.4 Method

5.4.1 Data method

AttributesTypes ofparameterdescription
$setFunctionkey: string, value: anyAdd new data attributes or modify existing data attributes. Usage: this.$set('key',value).
$deleteFunctionkey: stringDelete data attributes. Usage: this.$delete('key').
export default {
  data: {
    appInfo: {
      OS: 'HarmonyOS',
      Version: '2.0',
    },
  },
  changeAppInfo() {
    this.$set('appInfo.Version', '3.0');
    console.log(this.appInfo);
    this.$delete('appInfo');
    console.log(this.appInfo);
  }
}

5.4.2 Event method

In Hongmeng, you can use the $watch method to observe the property changes in the data. If the property value changes, the bound event will be triggered.

export default { 
  props: ['title'],
  onInit() {
    this.$watch('title', 'onPropChange');
  },
  onPropChange(newV, oldV) {
    console.info('title属性由'+ oldV +'变化为' + newV);
  },
}

5.5 Routing

{
  "pages": [
    "pages/index/index",
    "pages/detail/index"
  ]
}

The routing information of the page in the Hongmeng app is stored in pages in the src> main> config.json file. After @system.router is introduced, the push method is called to pass in the uri of the page that needs to be redirected to complete the redirection, or Use its back method to return to the home page.

import router from '@system.router';
export default {
  launch() {
    router.push ({
      uri: 'pages/detail/index',
    });
  },
  goBack() {
    router.back();
  }
}

Six, CSS syntax

CSS is a style language that describes the structure of HML pages. All components have system default styles. You can also customize different styles for components and pages in the page CSS style file.

6.1 Units of dimensions

There are two size units in Hongmeng, px (logical pixel) and percentage.

{
  "window": {
    "designWidth": 720,
    "autoDesignWidth": false
  }
}

The logical pixel configuration is in the window in the src> main> config.json file, designWidth is the logical width of the screen, the default is 720px, the page layout will be scaled to the actual width of the screen during actual display, such as 100px when the actual width is 1440 physical On a pixel screen, the actual rendering is 200 physical pixels.

When autoDesignWidth is set to true, the logical pixel px will be scaled according to the screen density. For example, 100px will actually be rendered as 300 physical pixels on a device with a screen density of 3.

The percentage unit represents the percentage of the component's size to the parent component. For example, if the width of the component is set to 50%, it means that its width is 50% of the parent component.

6.2 Style import

CSS style files support @import statements to import CSS files.

@import '../../common/style.css';

Seven, summary

Use Hongmeng’s JS SDK to develop apps. The overall project structure, life cycle, and development process are very similar to WeChat applets, and the syntax of hml and JS is very similar to Vue. The whole process is still very good for web developers. Friendly, I believe that all the friends who have the foundation of Web front-end development can get started quickly.

Due to limited space, there are many hardware call capabilities that Hongmeng gives developers that are not mentioned in the article. I hope Hongmeng can do better and better, so that more and more developers and users will join the grand ecology of Hongmeng.

8. Reference

Or follow the AOTULabs official account (AOTULabs) and push articles from time to time.


凹凸实验室
2.3k 声望5.5k 粉丝

凹凸实验室(Aotu.io,英文简称O2) 始建于2015年10月,是一个年轻基情的技术团队。