一、核心内容-商城
1、装饰器的拓展使用,基础组件的熟悉。
2、引入基础动画实战,页面属性动画、页面跳转动画、自定义页面翻页等。
3、一次开发,多端部署。
4、本地数据库实战,涉及多种本地数据存储方式。
5、路由导航:路由的拦截,根据登陆的权限来定义页面显示。
6、扩展知识:地图、定位等。
7、媒体查询、响应式布局等。
二、项目应用模块
鸿蒙系统是:1+8+n的生态,即"1"是手机,"8"是各种周边生态像耳机、车机、平板等,"n"指智能家居、智能办公等等。考虑到当前的项目要适应多端,即"一多开发",提出了新的开发模式,即多Module设计机制。
(1)多Module设计机制
1、支持模块化开发: 一个应用通常会包含多种功能,将不同的功能特性按模块来划分和管理,是一种良好的设计方式。通俗来讲就是可以将一个庞大的项目拆分为很多个模块,每个模块负责自己独立业务。有利于分工协作, 便于我们项目功能划分和维护, 每个模块可以**独立编译、运行。**他是鸿蒙系统提供的一种架构,按照指定模式来设计就能满足我们项目设计要求。
2、支持多设备适配: 一个应用往往需要适配多种设备类型,在采用多Module设计的应用中,每个Module都会标注所支持的设备类型。通俗来讲就是每个模块独立开发,并且每个模块都可以设置支持的设备类型,应用开发完成后上架市场,根据Module支持设备类型进行动态分配,如pad打开应用市场看到的就是支持pad的软件或者一些指定的模块。
(2)Module类型
Module按照使用场景可以分为两种类型:
1、Ability类型的Module: 这种模块可以独立编译、打包运行,相当于一个公司的子公司,可以独立运行也可以和总公司一起运行。对应到项目中,商城项目为主模块 ,物流信息:可以设计为一个子模块,这个模块可以和主模块一起放在手机上运行,也可以独立的放在车机、手表上面运行。
每一个Ability类型的Module编译后,会生成一个以.hap为后缀的文件,我们称其为HAP(Harmony Ability Package)包。HAP包可以独立安装和运行,是应用安装的基本单位,一个应用中可以包含一个或多个HAP包,具体包含如下两种类型。
- entry类型的Module:应用的主模块,包含应用的入口界面、入口图标和主功能特性,编译后生成entry类型的HAP。每一个应用分发到同一类型的设备上的应用程序包,只能包含唯一一个entry类型的HAP,也可以不包含。
- feature类型的Module:应用的动态特性模块,编译后生成feature类型的HAP。一个应用中可以包含一个或多个feature类型的HAP,也可以不包含。
2、Library类型的Module: 用于实现代码和资源的共享。相当于公司里的各个部门,必须 和总公司一起运行。对应到项目中,相当于一个庞大的项目我们可以拆分业务,放在每一个模块中运行,这些模块是无法独立打包运行,必须依赖整个项目。可以帮助我们分工协作,也可以帮助项目业务拆分后维护。一个模块类似于一个独立的项目,项目中要用到的公共工具或者代码,如果没有提取公共模块,每个模块重复写。
Library类型的Module分为Static和Shared两种类型,编译后会生成共享包。
- Static Library:静态共享库。编译后会生成一个以.har为后缀的文件,即静态共享包HAR(Harmony Archive Package)。
- Shared Library:动态共享库。编译后会生成一个以.hsp为后缀的文件,即动态共享包HSP(Harmony Shared Package)。
共享包类型 | 编译和运行方式 | 发布和引用方式 |
---|---|---|
HAR | HAR中的代码和资源跟随使用方编译,如果有多个使用方,它们的编译产物中会存在多份相同拷贝。 注意:编译HAR时,建议开启混淆能力,保护代码资产。 | HAR除了支持应用内引用,还可以独立打包发布,供其他应用引用。 |
HSP | HSP中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份。 | HSP一般随应用进行打包,当前支持应用内和集成态HSP。应用内HSP只支持应用内引用,集成态HSP支持发布到ohpm私仓和跨应用引用。 |

(3)HAP、HAR和HSP区别
模块 | 区别 |
---|---|
HAP | 可以代表独立的项目,打包后缀名为hap,可以独立运行到设备,也可以独立上架应用市场。 |
HAR | 与HSP一样都是属于无法独立运行,但是可以将模块放在主模块使用,与HSP的区别在于:HAR模块一旦被主模块或者features模块使用,打包的时候独立打包一份代码放在对应模块中,所以多个模块使用,打包会打包多份文件,适合用于存放项目中指定某些业务,从主模块中独立出来,在商城项目中,可以将支付模块、购物车模块、商品列表都独立为HAR,在页面中引入使用。 |
HSP | type类型为shared,打包后的包名是hsp格式,无法独立编译和运行,必须依赖于entry或者application模块来运行。任何一个模块都可以引入shared模块中的内容,可以当成公共共享模块。 特点:多个模块引入shared模块内容,最终项目打包只会生成一个hsp模块进行代码的共享。 |
三、一次开发,多端部署
随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用、互助共享,让用户享受无缝的全场景体验。HarmonyOS系统面向多终端提供了"一次开发,多端部署"(后文中简称为"一多")的能力,让开发者可以基于一种设计,高效构建多端可运行的应用。
一多开发主要包含两个层面:1、多个设备终端都 能适配运行,不同设备屏幕能看到不同的布局方案。2、根据不同终端设备打包为不同的HAP,在每一个终端设备中就能下载对应的安装包。
小设备 | 中设备 | 大设备 | |
---|---|---|---|
![]() |
![]() |
![]() |
若要完成一多开发,我们需要将项目架构按照官方标准三层目录结构来设计。
需要用到的技术:**工程管理、媒体查询 、栅格系统,**在开发过程中用媒体查询和栅格系统一起来实现页面的布局。
(1)工程管理
当遇到需要多端适配的项目时,推荐使用官方推荐的三层目录架构。以后所有HAP 默认放在product ;common 就是HSP 模块,用于存放公共工具和代码;features 模块就是HAR模块,可以将项目拆分为无数个模块独立管理。
/application
├── common # 公共特性目录
│
├── features # 功能模块目录
│ ├── feature1 # 子功能
│ ├── feature2 # 子功能2
│ └── ... # 子功能n
│
└── product # 产品层目录
├── wearable # 智能穿戴泛类目录
├── default # 默认设备泛类目录
└── ...
按照官方文档,修改项目目录如下:

(2)媒体查询技术
1、基本概念与基础语法
响应式布局方式,可以检测当前设备大小,根据不同的屏幕尺寸用户自己决定如何布局。媒体查询技术是实现响应式布局的核心技术。
响应式布局能力 | 简介 |
---|---|
断点 | 用户可以自己设置屏幕的参考值,以这个值为准让屏幕大小来匹配,匹配完成后就采用某种布局。 |
媒体查询 | 检测屏幕大小,检测设备类型。 |
栅格系统 | 在媒体查询技术上封装好的技术,鸿蒙提供的栅格系统 |
媒体查询:
使用媒体查询来检测屏幕显示方式,下面代码中只用到了媒体查询的一个条件,只判断了横屏竖屏,要真正实现页面上元素的检测,尺寸的检测,可以添加更多的条件。
javascript
//(1)引入媒体查询对象
import mediaquery from '@ohos.mediaquery';
//目前官方提供从Kit中获取
import { mediaquery } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State message:string = "媒体查询技术";
//(2)检测屏幕是否为横屏,orientation:landscape查询条件:屏幕格式
private listener =mediaquery.matchMediaSync('(orientation:landscape)')
//(4)当满足媒体查询条件时,触发回调
onPortrait = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
if (mediaQueryResult.matches) {
AlertDialog.show({message:"横屏"})
}else {
AlertDialog.show({message:"竖屏"})
}
}
//(3)给listener监听器绑定一个函数
aboutToAppear(): void {
this.listener.on("change",this.onPortrait)
}
build() {
Column(){
Text(this.message)
.fontSize(50)
}
.width('100%')
.height('100%')
.backgroundColor(Color.Green)
}
}
2、媒体查询条件
内体查询条件是一个完整的表达方式,由媒体类型、逻辑操作符、媒体特征组成。
文档链接详情:媒体查询 (@ohos.mediaquery)-构建布局-开发布局-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者
名称 | 特征 |
---|---|
媒体类型 | screen是默认的类型,不写也默认这个类型。一般将screen表示彩色屏幕。 |
逻辑操作符 | 用于链接多个条件的符号,and:"与";or:"或";not:必须搭配screen使用,取反媒体查询结果;等等 |
媒体特征 | 用于指定设备的范围,包含设备的状态、大小、名字。比较height、width等宽高尺寸,resolution分辨率,orientation屏幕的方向 |
javascript
private listener =mediaquery.matchMediaSync('(320vp<=width<600vp)')
//修改此处查询条件,根据不同的查询返回结果来定义不同的样式属性
javascript
//(1)引入媒体查询对象
import mediaquery from '@ohos.mediaquery';
@Entry
@Component
struct Index {
@State message:string = "媒体查询技术";
//(2)检测屏幕宽度
private listener =mediaquery.matchMediaSync('(320vp<=width<600vp)')
//(4)当满足媒体查询条件时,触发回调
onPortrait = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
if (mediaQueryResult.matches) {
AlertDialog.show({message:"手机"})
}else {
AlertDialog.show({message:"其他设备"})
}
}
//(3)给listener监听器绑定一个函数
aboutToAppear(): void {
this.listener.on("change",this.onPortrait)
}
build() {
Column(){
Text(this.message)
.fontSize(50)
}
.width('100%')
.height('100%')
.backgroundColor(Color.Green)
}
}
3、封装媒体查询工具
需求:根据屏幕大小来自动识别我们的设备类型,设备尺寸目前主要分为xs,sm,md,lg,封装工具按照下面的断点来实现页面变化,检测设备的类型。
参考断点:
断点名称 | 取值范围(vp) |
---|---|
xs | [0, 320) |
sm | [320, 600) |
md | [600, 840) |
lg | [840, +∞) |
3.1 媒体查询常量:
在开发媒体查询的时候,我们会用到很多的数字或者一些值,这些数字或者值,尽量不要直接硬编码到代码中,有必要将代码中常用的参数封装到常量文件中,页面用来调用。在entry或者default的项目中未来让页面显示内容更加规范,因此也定义了一个常量文件,位置default/ets/constants/BasicConstants.ets
javascript
//default/src/main/ets/Constants/BasicConstants
//常量文件:封装了页面常用的一些值,封装好了以后可以直接引用,不用再写一遍
//减少页面数字、结果的硬编码
export class BasicContants{
//常量要求变量名字必须大写 readonly只读
static readonly FULL_WIDTH = '100%'
static readonly FULL_HEIGHT = '100%'
static readonly FONT_SIZE_SMALL = '14vp'
static readonly FONT_SIZE_MEDIUM = '16vp'
static readonly FONT_SIZE_BIG = '20vp'
static readonly FONT_SIZE_LARGE = '30vp'
}
在页面中使用:
javascript
import {BasicContants} from '../Constants/BasicContants'
@Entry
@Component
struct Index {
@State message:string = "常量使用";
build() {
Column(){
Text(this.message)
.fontSize(BasicContants.FONT_SIZE_LARGE)
}
.width(BasicContants.FULL_WIDTH)
.height(BasicContants.FULL_HEIGHT)
}
}
3.2 媒体查询工具:
其属于公共开发工具,以后任何HAP模块,或者其他模块都可以使用这个工具,因此代码放在common的HSP模块中进行封装,哪个模块使用,直接引入共享。
3.2.1 封装常量
开发过程中,媒体查询有很多常量需要使用,这些常量都封装为一个媒体查询的常量文件,考虑到媒体查询工具是公用的工具,我们可以将这个工具放在common模块中的utils中,将常量文件放在common/src/main/ets/constants文件夹下,此处命名为BreakPointConstants,译为"媒体查询断电点常量"。
javascript
/**
*Constants for breakpoint
*/
export class BreakPointConstants{
/**
*这个单位页面上表示初始值
*/
static readonly BREAKPOINT_INIT = 'init';
/**
* 这个单位页面上表示手机
*/
static readonly BREAKPOINT_SM = 'sm';
/**
* 这个单位页面上表示折叠屏
*/
static readonly BREAKPOINT_MD = 'md';
/**
* 这个单位页面上表示pad
*/
static readonly BREAKPOINT_LG = 'lg';
/**
*这个单位页面上表示大屏
*/
static readonly BREAKPOINT_XL = 'xl';
/**
*这个单位页面上表示超大屏
*/
static readonly BREAKPOINT_XXL = 'xxl';
/**
*断点数组,根据不同的尺寸大小说明修改数组样式
*/
static readonly BREAKPOINT_VALUE:Array<string> = ['320vp','600vp','840vp','1080vp','1280vp'];
/**
*列在水平方向占多少份
*/
static readonly COLUMN_SM:string = '4';
static readonly COLUMN_MD:string = '8';
static readonly COLUMN_LG:string = '12';
/**
*
*/
static readonly GUTTER_X:number = 12;
/**
*
*/
static readonly SPAN_SM:number = 4;
static readonly SPAN_MD:number = 6;
static readonly SPAN_LG:number = 8;
/**
*
*/
static readonly OFFSET_MD:number = 1;
static readonly OFFSET_LG:number = 2;
/**
*
*/
static readonly CURRENT_BREAKPOINT:string = 'currentbreakpoint';
/**
*
*/
static readonly FONT_SIZE_SM:number = 14;
static readonly FONT_SIZE_MD:number = 16;
static readonly FONT_SIZE_LG:number = 18;
/**
*
*/
static readonly COVER_MARGIN_SM:number = 10;
static readonly COVER_MARGIN_MD:number = 30;
static readonly COVER_MARGIN_LG:number = 40;
/**
*
*/
static readonly RANGE_SM:string = '(320vp<=width<600vp)';
static readonly RANGE_MD:string = '(600vp<=width<840vp)';
static readonly RANGE_LG:string = '(840vp<=width<1080vp)';
static readonly RANGE_XL:string = '(1080vp<=width<1280vp)';
static readonly RANGE_XXL:string = '(1280vp<=width)';
}
3.2.2 封装媒体查询工具
在common/src/main/ets/utils创建一个媒体查询公共代码,BreakPointSystem.ets文件
javascript
import {BreakPointConstants} from '../constants/BreakPointConstants'
import { mediaquery } from '@kit.ArkUI'
export class BreakPointSystem{
//当前尺寸是多大,媒体查询,得到单位要将这个sm、md、lg、xl、xxl保存到全局,currentBreakpint作为key保存起来
private currentBreakpint:string = BreakPointConstants.BREAKPOINT_INIT
/**
*步骤一:屏幕大小的条件查询
*/
private smListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_SM)
private mdListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_MD)
private lgListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_LG)
private xlListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_XL)
private xxlListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_XXL)
//定义一个公共函数,用来保存当前屏幕的检测结果
//将sm、md、lg、xl、xxl保存到"应用的状态"
private updateCurrentBreakpoint(breakpoint:string){
if (this.currentBreakpint !== breakpoint) {
this.currentBreakpint = breakpoint
//将当前单位做应用存储,setOrCreate是创建初始化的意思,()中存储一个键值,名字和存储内容
AppStorage.setOrCreate<string>(BreakPointConstants.CURRENT_BREAKPOINT,this.currentBreakpint)
}
}
/**
*步骤二:给监听器绑定"change"事件
*/
private isBreakpointSM = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
//如果匹配成功
if (mediaQueryResult.matches) {
//将sm的单位保存起来
this.updateCurrentBreakpoint(BreakPointConstants.BREAKPOINT_SM)
}
}
private isBreakpointMD = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
//如果匹配成功
if (mediaQueryResult.matches) {
//将md的单位保存起来
this.updateCurrentBreakpoint(BreakPointConstants.BREAKPOINT_MD)
}
}
private isBreakpointLG = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
//如果匹配成功
if (mediaQueryResult.matches) {
//将lg的单位保存起来
this.updateCurrentBreakpoint(BreakPointConstants.BREAKPOINT_LG)
}
}
private isBreakpointXL = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
//如果匹配成功
if (mediaQueryResult.matches) {
//将xl的单位保存起来
this.updateCurrentBreakpoint(BreakPointConstants.BREAKPOINT_XL)
}
}
private isBreakpointXXL = (mediaQueryResult: mediaquery.MediaQueryResult)=>{
//如果匹配成功
if (mediaQueryResult.matches) {
//将xxl的单位保存起来
this.updateCurrentBreakpoint(BreakPointConstants.BREAKPOINT_XXL)
}
}
//这个函数外面要调用,因此不能再用private修饰
public register(){
this.smListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_SM);
this.smListener.on('change',this.isBreakpointSM);
this.mdListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_MD);
this.mdListener.on('change',this.isBreakpointMD);
this.lgListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_LG);
this.lgListener.on('change',this.isBreakpointLG);
this.xlListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_XL);
this.xlListener.on('change',this.isBreakpointXL);
this.xxlListener = mediaquery.matchMediaSync(BreakPointConstants.RANGE_XXL);
this.xxlListener.on('change',this.isBreakpointXXL);
}
//接触事件绑定,优化代码
public unregister(){
this.smListener.off('change',this.isBreakpointSM);
this.mdListener.off('change',this.isBreakpointMD);
this.lgListener.off('change',this.isBreakpointLG);
this.xlListener.off('change',this.isBreakpointXL);
this.xxlListener.off('change',this.isBreakpointXXL);
}
}
3.2.3 工具暴露
在common/index.ets下
javascript
export { BreakPointConstants } from './src/main/ets/constants/BreakPointConstants'
export { BreakPointSystem } from './src/main/ets/utils/BreakPointSystem';
3.2.4 导入使用
在default/ets/Index.ets下,以后便可以根据得到的单位来决定页面如何布局,当检测sm的时候,一行显示两个商品,当检测md的时候,一行可以显示四个商品,当检测到lg的时候,一行可以多显示一些商品等响应式方案。
javascript
import {BreakPointSystem,BreakPointConstants} from '@ohos/common'
import {BasicContants} from '../Constants/BasicContants'
@Entry
@Component
struct Index {
//暴露除一个类,需要new实例化才能使用
private breakpointSystem = new BreakPointSystem()
@StorageProp("currentbreakpoint") currentBreakpoint:string = BreakPointConstants.BREAKPOINT_INIT
aboutToAppear(): void {
//进入界面想要注册监听器,工具中已经将值传到了全局AppStorage
this.breakpointSystem.register()
}
aboutToDisappear(): void {
//组件销毁时要将监听器销毁,利于内存的回收
this.breakpointSystem.unregister()
}
build() {
Column(){
Text(`当前屏幕尺寸单位类型为:${this.currentBreakpoint}`)
.fontSize(BasicContants.FONT_SIZE_LARGE)
}
.width(BasicContants.FULL_WIDTH)
.height(BasicContants.FULL_HEIGHT)
}
}
3.3.5 注意事项
1、因为工具封装暴露的是一个类,因此引入这个工具过后需要实例化一次。
javascript
private breakpointSystem = new BreakPointSystem()
2、在页面生命周期中进行注册和销毁。
javascript
aboutToAppear(): void {
//进入界面想要注册监听器,工具中已经将值传到了全局AppStorage
this.breakpointSystem.register()
}
aboutToDisappear(): void {
//组件销毁时要将监听器销毁,利于内存的回收
this.breakpointSystem.unregister()
}
3、通过应用存储获取当前检测到的屏幕尺寸。
javascript
@StorageProp("currentbreakpoint") currentBreakpoint:string = BreakPointConstants.BREAKPOINT_INIT
4、如果想要在全局存储使用,但是不是页面或者组件中,而是在一个class类中进行只存操作,那么我们可以用setOrCreate来实现。
javascript
AppStorage.setOrCreate<string>(BreakPointConstants.CURRENT_BREAKPOINT,this.currentBreakpint)
**注意:**新版本官方文档明确表示引用HSP的模块不支持预览,官方说明:
- 预览不支持引用HSP。引用了HSP的模块不支持预览,请直接在HSP内预览或模拟HSP。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-previewer-arkts-js-V5
书写时可以先在HAP或者HAR中实现,如有需要再往出抽离。
(3)栅格系统
栅格系统相当于鸿蒙已经封装好的组件,可以实现在页面布局中,根据屏幕大小来决定元素排列规则。栅格系统的底层其实也是用到了媒体查询技术。
栅格的样式由Margin、Gutter、Columns三个属性决定。

单个Column的宽度是系统结合Margin、Gutter和Columns自动计算的,不需要也不允许开发者手动配置。在实际使用场景中,可以根据需要配置不同断点下栅格组件中元素占据的列数,同时也可以调整Margin、Gutter、Columns的取值,从而实现不同的布局效果。
| 名称 | 简介 |
| Margin | 相对应用窗口、父容器的左右边缘的距离,决定了内容可展示的整体宽度。 |
| Gutter | 相邻的两个Column之间的距离,决定内容间的紧密程度。 |
Columns | 栅格中的列数,其数值决定了内容的布局复杂度,默认最多12列。 |
---|
1、栅格容器组件GridRow
栅格组件提供了丰富的断点定制能力,开发者可以修改断点的取值范围,支持启用最多6个断点。
javascript
//基础代码
@Entry
@Component
struct GridRowSample1 {
@State bgcolors:Color[]=[Color.Red, Color.Blue, Color.Yellow, Color.Green, Color.Gray, Color.Black,Color.Pink,Color.Orange]
build() {
GridRow(){
ForEach(this.bgcolors, (item:Color, index) => {
GridCol(){
Text(`${index}`)
.textAlign(TextAlign.Center)
.backgroundColor(item)
.width(30)
.height(100)
}
}, (item:Color, index) => JSON.stringify(item))
}
}
}
栅格组件(GridRow)的直接孩子节点只可以是栅格子组件(GridCol),默认一行最多显示12个元素,代表12列栅格布局,栅格布局是一种设计流程,很多框架都会采用,每一家框架的设计会有所区别。
1.1 GridRow支持参数
columns自定义设置一行最多显示多少列,用columns属性来控制。
javascript
//sm最多显示三列
GridRow({columns:3}){
}
可以指定根据不同的屏幕尺寸设计不同的元素排列个数。
javascript
//sm最多显示三列,md最多显示8列
GridRow({columns:{sm:4,md:8}}){
}
breakpoints允许用户根据屏幕来自定义断点值。默认情况下,官方提供4个断点,最多支持6个断点。
断点名称 | 取值范围(vp) |
---|---|
xs | [0, 320) |
sm | [320, 600) |
md | [600, 840) |
lg | [840, +∞) |
javascript
//sm最多显示三列,md最多显示8列
GridRow({columns:{sm:4,md:8}},
//自定义断点:200vp便是sm,300vp表示md......
breakpoints:{value:['200vp','300vp','400vp','500vp','600vp']}
){
}
direction可以设置容器里面子元素排列数序,主要是Row和RowReverse。
javascript
//sm最多显示三列,md最多显示8列
GridRow({columns:{sm:4,md:8}},
//自定义断点:200vp便是sm,300vp表示md......
breakpoints:{value:['200vp','300vp','400vp','500vp','600vp']},
direction:GridRowDirection.Row
){
}
gutter设置子元素在水平方向排列过程中默认的间距。
javascript
//sm最多显示三列,md最多显示8列
GridRow({columns:{sm:4,md:8}},
//自定义断点:200vp便是sm,300vp表示md......
breakpoints:{value:['200vp','300vp','400vp','500vp','600vp']},
direction:GridRowDirection.Row,
gutter:10
){
}
1.2 子组件GridCol支持参数
GridCol组件支持配置span、offset和order三个参数。
javascript
//sm最多显示三列,md最多显示8列
GridRow({columns:{sm:4,md:8}}
){
//span参数可以设置指定每一个单元格的份数
GridCol({span:{sm:2,md:4},
//offset可以通过这个属性来控制当前盒子的偏移份数,相当于设置了margin-left。
offset:1,
//order可以用来改变盒子排列的前后顺序
}){
}
}
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
span | {xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?:number} | 是 | - | 在栅格中占据的列数。span为0,意味着该元素既不参与布局计算,也不会被渲染。 |
offset | {xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?:number} | 否 | 0 | 相对于前一个栅格子组件偏移的列数。 |
order | {xs?: number, sm?: number, md?: number, lg?: number, xl?: number, xxl?:number} | 否 | 0 | 元素的序号,根据栅格子组件的序号,从小到大对栅格子组件做排序。 |
2、栅格布局典型布局
典型页面场景-布局能力-页面开发的一多能力介绍-一次开发,多端部署 - 华为HarmonyOS开发者
四、Module构建流程
(1)HAP包构建流程
1、以一个单独的商城项目中地图功能作为一个模块为例,选中项目鼠标右键新建模块,

2、 回跳到选择构建模块类型,选择第一个,

3、填写修改module名字,因为只能有一个entry,所以我们建立feature类型,可以有多个feature类型。

4、默认Ability名字即可,
5、创建成功,以后可以把地图、支付相关的一些功能独立出去放在这个模块,多个模块之间是可以进行通信的。

6、想要设置HAP打包后可以在什么设备运行,需要在/src/main/module.json下的"deviceTypes"中设置允许设备类型:

(2)HSP包构建流程
1、与上述构建HAP类型,但在选择模块时选择Shared Library

2、名字取名为common,

3、创建成功,在项目中我们一般只会创建一个shared模块,里面会放一些我们公共的工具包、公共组件都会存放在common模块中,其他ability模块中引入使用。

4、查看common模块类型,在common/module.json5下查看:

5、每个模块都能引入这个common模块中的内容,但是在最后打包的时候只会产生一份hsp代码,减少代码体积,以后修改了公共代码,其他页面都将直接修改。
6、暴露公共代码时,common里面写的代码基本上都是其他模块要用的公共代码,所以代码写完了将对象内容暴露出去,其他模块才能引入。在common/index.ets下书写,因此只要在这个文件暴露出去了指定组件、工具、插件等,其他模块就可以使用。

7、common是一个独立的模块,里面的内容如果需要使用,需要将common模块引入到其他模块中做成一个依赖项,其他模块在开发代码的时候,找对应的某个函数,先找自己本身有没有,如果没有内容,就会去找依赖项中有没有,在oh_modules文件夹下存放自己的依赖和第三方依赖。比如common模块就是自己的依赖,axios属于第三方依赖。

在devDependencies下将common包添加到全局依赖下
javascript
"devDependencies": {
"@ohos/hypium": "1.0.21",
"@ohos/hamock": "1.0.0",
"@ohos/common": "file:./common"
}
**ps:**写入后一定要记得执行Run,才算打包。

但这样会报错, 解决方法如下图:

这样在@ohos下边有了相应的依赖包。
(3)HAR包构建流程
1、在项目目录下创建一个文件夹features,

2、选中features,右键创建一个module,

3、根据模块需求定义模块名字,这个文件下创建的模块都是HAR模块,

4、打开指定模块的module.json5文件,

5、暴露公共代码时,在对应的模块中找到对应的index.ets ,
javascript
export { MainPage } from './src/main/ets/components/MainPage';
在主模块中引入指定homelibrary, 方法类似HSP需要在oh-package.json5修改,并且Run打包,

这样在相应位置便有了依赖包,可以在entry或者其他HAP处导入。
