鸿蒙开发学习笔记
新技术开发要点
- 样式书写
- 页面布局方式
- 图片加载
- 本地缓存
- 组件定义
- 父子组件数据通讯
- 状态数据管理
- 网络请求,数据渲染
- 打包,发布上线
- Canvas, WebGL
- 动画效果
- 页面路由
- 启动页
- 组件生命周期
- 页面生命周期
个人总结
UI渲染方式:函数声明式渲染UI
常用布局组件:Row, Column, Flex, 类似Flex布局
数据类型声明方式:以Class进行声明
所有数据响应更新机制:只会监听第一层级数据变化(对象,数组)
页面入口规则: 每个页面必需只能有一个@Entry修改,被@Enty修改的组件必需要有一个容器组件
函数声明调用形式:箭头函数
组件如何复用:
UI渲染笔记
差异样式属性
.LayoutWeight(1) , 定义 如分配剩余宽高
.aspectRatiio(1) 定义正比宽高
声明响应式数据
使用@State修饰数据
@State name: string = "Hello World."
声明自定义函数组件
使用@Builder修饰函数
注意:该函数组件不会响应@State修饰的基础数据类型的变化,可以响应引用类型数据的变化(不能直接传入@State修饰的数据,要单独写一个{obj: xxx}数据),类似React中的memo方法
@Builder function TextComp(){
Row(){
Text("Hello Text")
}
}
声明复用样式
使用@Style修改样式函数
@Styles function textStyle(){
.width(100)
.height(50)
}
// 以继承的方式修改某类弄组件
@Extend(Button) function textStyle(){
.width(120)
.height(60)
.borderRadius(30)
.backgroundColor(Color.Brown)
}
状态样式
stateStyles
// way 2
@Styles pressStyle() {
.width(200)
.height(100)
.backgroundColor(Color.Pink)
}
Button("Test2")
.stateStyles({
pressed: {
.width(100)
.backgroundColor('red')
},
normal: pressStyle,
focused: {
},
disabled: {
}
})
类似renderFunction(插槽)Prop声明
@BuilderParam修饰的Prop值需为@Builder修饰的方法
@Component
struct MyComp(){
@BuilderParam
getContent: () => void = () => {}
build(){
}
}
方式二:尾随闭包
当组件只有一个@BuilderParam修改的方法时,可以使用MyComp(){...UIComp}形式传入Prop
条件循环渲染
if...else...
ForEach(arr, itemGenerator, keyGenerator)
图片资源加载
-
本地图片加载
Image(/assets/img.png) -
Resource资源加载
$r('app.media.img.png') -
rawfile资源加载
$rawfile('app.img.png')
数据通讯
- 父组件向子组件传递Prop数据,直接使用对象
{data: xxx}传递到子组件 ,子组件中需要声明对应的属性值(只是单向数据传递,不会响应数据变化更新) - 父组件向子组件传递数据,子组件中用
@Prop修改属性,会根据父组件数据变化重新渲染(数据为单向传递) - 父组件向子组件传递数据,子组件中用
@Link修改属性,父组件传递数据用$xxx_data进行传递(类似引用传递),会根据父组件数据变化重新渲染(数据为双向传递) @Provide, @Consume实现跨组件状态共享,可以给@Provide("name"), @Consum("name")重命名- 可以使用
@Watch("funName")来监听@Prop, @Link, @Provide, @State修饰数据的变化,组件第一次渲染不会执行 @Observed, @ObjectLink,实现数据双向绑定,数据变化可重新渲染UI
共享数据的管理
-
页面级数据共享
LocalStorage, 通过LocalStorage对象生成共享数据(可导出,内存级数据共享),在页面@Entry(localStorageData)入口传入数据,在页面组件中使用@LocalStorageProp("key")、@LocalStorageLink("key")修饰来获取数据,非本地持久存储。 -
应用级数据共享
AppStorage, 通过AppStorage.SetOrCreate(key, val)来添加数据,通过@StorageProp('key'), @StorageLink('key')来获取数据,也可以使用AppStorage.Get<T>('key')来获取。 -
持久化存储
PersistentStorage,可以使用PersistentStorage.PersistProp('key'),来声明持久化AppStorage中存储的数据。
页面路由跳转
router.pushUrl({url: "pages/xxx.ejs" })router.replaceUrl({url: "pages/xxx.ejs" })router.back(),带参数返回必须传urlrouter.getParams()可以获取页面传递进来的参数router.RouterMode.Standard, router.RouterMode.Single
页面生命周期
aboutToAppear(){}: 组件加载,类似ComponentDidMount,可以在这里发送数据请求onPageShow(){}:当页面显示时执行该方法,只在被@Entry修饰的组件生效onPageHide(){}:当页面隐藏时执行该方法,只在被@Entry修饰的组件生效onBackPress(){}:当用户点击返回按钮时执行该方法,只在被@Entry修饰的组件生效abouttoDisappear(){}: 组件销毁,类似ComponentDidUnmount
UIAbility生命周期
-
onCreate -
onDestory -
onWindowStageCreate -
onnWindowStateDestory -
onForeground -
onBackground
调起一个Ability
Button("去支付")
.onClick(() => {
const context = getContext(this) as common.UIAbilityContext
const want: Want = {
bundleName: 'com.xxx.xxx',
abilityName: 'xxxAbility'
}
context.startAbility(want, () => {
})
})
疑问
- 一个UIAbility 有何作用?一个应用多个UIAbility有何作用?(一个UIAbility对应一个后台任务)
AppStorage.setAndLink()如何使用,作用是什么? (可以设置并获得对应属性的双向绑定数据,可以进行set和get)