#HarmonyOS NEXT体验官#梅科尔工作室HOS-HarmonyOS NEXT应用零基础教学(二) 原创
3 HarmonyOS 装饰器与事件:
本模块主要讲解ArkTS装饰器与基础事件,使其能实现动态页面跳转。
3.1 触控事件
ArkUI触控事件,根据输入源不同,主要划分为touch类与mouse类。
touch类的输入源包含:Finger(手指)、Pen(笔)
mouse类的输入源包含:Mouse(鼠标)、Touchpad(触控板)、Joystick(手柄)
上述触控事件想要被触发,需要在事件方法的回调中添加组件响应逻辑。
通过事件方法可以配置组件支持的事件, 事件方法紧随组件并用“.”运算符连接。使用Lambda表达式配置组件的事件方法:
(parameters) -> expression 或
(parameters) ->{ statements; }
例如,为Button组件添加点击onClick方法,在onClick方法的回调中添加点击响应逻辑。
Button("点击事件")
.onClick(()=>{
this.age=this.age+1
})
3.2路由跳转
页面路由:是指在应用程序中实现不同页面之间的跳转和数据传递。
Router有两种页面跳转模式:
①router.pushUrl( ):目标页不会替换当前页,而是压入页面栈中,因此可以用router,back( )返回当前页。
②router.replaceUrl( ):目标页替换当前页,当前页会被销毁并释放资源,无法返回当前页。
此外Router有两种页面实例模式:
①Standard:标准实例模式,每次跳转都会新建一个目标页并压入栈顶。默认就是这种模式
②Single:单实例模式,如果目标页已经在栈中,则离栈顶最近的同UrT页面会被移动到栈顶并重新加载。
注意:页面栈的最大容量上限为32个页面,使用router.clear( )方法可以清空页面栈,释放内存
//导入ArkUI的路由模块
import { router } from '@kit.ArkUI'
@Entry
@Component
struct Login {
build() {
Column(){
Button("点击事件")
.onClick(()=>{
router.pushUrl({
url:"pages/Enroll"
})
})
}
}
}
3.3 HarmonyOS 装饰器
装饰器:用来装饰类、结构体、方法以及变量,赋予其特殊的含义,如 @Entry 、@Component 、 等这个状态变化会引起 UI 变更。
ArkTS装饰器分为三大类:组件定义装饰器、动态构建装饰器、状态管理装饰器。
组件定义装饰器
@ Entry
@Entry装饰的自定义组件用作页面的默认入口组件,加载页面时,将首先创建并呈现
作为一个入口组件,先载入@Entry,再载入其他组件。只有被@Entry和@Preview修饰的组件才能用预览器进行预览展示。
而在真机模拟时,通过在src/main/ets/entryability/EntryAbility.ets文件中在onWindowStageCreate配置应用启动刷新界面,此路径所在文件必须为被 @ Entry所装饰。
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
//配置下方路径
windowStage.loadContent('pages/Load', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
}
@Preview
用@Preview装饰的自定义组件可以在DevEco Studio的预览器上进行预览,加载页面时将创建并呈@Preview装饰的自定义组件。与@Entry不同的是,被@Preview装饰预览的是当前自定义组件,而前者预览的则是整个界面。
使用场景:①当存在有多个结构体,查看指定的结构体②查看静态类型自定义组件
//预览组件 test1
@Preview
@Component
struct test1 {
build() {
Column(){
Button("你好")
}
}
}
//预览组件 test2
@Preview
@Component
struct test2 {
build() {
Column(){
Button("你好")
}
}
}
//预览组件 test3
@Preview
@Component
struct test3 {
build() {
Column(){
Button("你好")
}
}
}
@Component
@Component装饰的struct表示该结构体具有组件化能力,能够成为一个独立的组件,即自定义组件,在build方法里描述UI结构。
其本身拥有四大特性:
①可组合:允许开发人员组合使用内置组件、其他组件、公共属性和方法
②可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用
③生命周期:生命周期的回调方法可以在组件中配置,用于业务逻辑处理
④数据驱动更新:由状态变量的数据动,实现UI自动更新
@Component创建的子组件可以被调用,一种为本文件内调用:
//父组件
@Entry
@Component
struct Index {
build() {
Column({space:20}) {
//调用子组件
button1()
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
//子组件button1
@Component
struct button1{
build(){
Column(){
/* 显示年龄的按钮,点击增加年龄 */
Button("按钮")
.type(ButtonType.Normal)
.borderRadius(10)
}
}
}
另一种为跨文件调用,需要通过import导入
//Import.ets
import { Export } from './Export'
@Entry
@Component
struct Export {
build() {
Column({space:20}) {
//调用子组件
Import()
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
//Export
@Component
export struct Export{
build(){
Column(){
/* 显示年龄的按钮,点击增加年龄 */
Button("按钮")
.type(ButtonType.Normal)
.borderRadius(10)
}
}
}
动态UI装饰器
@ Builder
@Builder装饰的方法用于定义组件的声明式UI描述,在一个自定义组件内快速生成多个布局内容当封装完自定义组件,但是只想调用其中的某个组件,不想单起文件,用@Builder
由于buttoner定义在了build()过程外面,struct里面,所以调用要用this.buttoner()
@Entry
@Component
struct Index {
//自定义按钮
@Builder buttoner(){
Button("自定义按钮")
.fontSize(50)
}
build() {
Column({space:20}) {
//调用子组件
Button("按钮1")
this.buttoner()
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
@Styles
将新的属性函数添加到基本组件上,如Text、Column、Button等。通过@stvles装饰器可以快速定义并复用组件的自定义样式。
@Entry
@Component
struct Index {
build() {
Column({space:20}) {
//调用子组件
Button("你好")
.card()
Button("你好")
.card()
Button("你好")
.card()
}
}
}
// 自定义组件样式。
@Styles function card(){
.width("50")
.height("50")
.backgroundColor(Color.Red)
}
动态UI装饰器
@State
@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新。
如下方当点击按钮时,修改message,Text文本组件中绑定this.messageText文本会发生改变。
@Entry
@Component
struct Index {
@state message:string = "Hello World"
build() {
Column({space:20}) {
Text(this.message)
Button("点击改变")
.onClick(()=>{
this.message="你好 世界"
})
}
}
}
@Prop
@Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组
件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但更改不会通知给父
组件,即@Prop属于单向数据绑定。
@Prop状态数据具有以下特征:
①支持简单类型:仅支持number、string、boolean简单类型;
②私有:仅在组件内访问;
③支持多个实例:一个组件中可以定义多个标有@Prop的属性;
@Entry
@Component
export struct Index {
@State agef:number=18
build() {
Column({space:20}) {
Text(this.agef.toString()).fontSize(50)
/* 父亲按钮,点击增加年龄 */
Button("父亲按钮"+this.agef)
.onClick(()=>{
this.agef=this.agef+1
})
/* 调用子组件button1,传递(单向)年龄属性 */
button1({age:this.agef})
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
/**
* 子组件button1
* @Prop 单向绑定
*/
@Component
struct button1{
@Prop age:number
build(){
Column(){
/* 显示年龄的按钮,点击增加年龄 */
Button("单向数据"+this.age)
.type(ButtonType.Normal)
.borderRadius(10)
.onClick(()=>{
this.age=this.age+1
})
}
}
}
@Link
创建自定义组件时需要将变量的引用传递给@Link变量,在创建组件的新实例时,必须
使用命名参数初始化所有@Link变量。@Link变量可以使用@State变量或@Link变量的引
用进行初始化,@State变量可以通过“$”操作符创建引用。@Link装饰的变量可以和父组件的@State变量建立双向数据绑定。
@Link状态数据具有以下特征:
①支持多种类型:@Link变量的值与@State变量的类型相同,即cass、number、string、boolean或这些类型的数组;
②私有:仅在组件内访问;
③单个数据源:初始化@Link变量的父组件的变量必须是@State变量;
@Entry
@Component
export struct Index {
@State agef:number=18
build() {
Column({space:20}) {
Text(this.agef.toString()).fontSize(50)
/* 父亲按钮,点击增加年龄 */
Button("父亲按钮"+this.agef)
.onClick(()=>{
this.agef=this.agef+1
})
/* 调用子组件button2,链接(双向)年龄属性 */
button2({age:$agef})
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
/**
* 子组件button2
* @Link 双向绑定
*/
@Component
struct button2{
@Link age:number
build(){
Column(){
/* 显示年龄的按钮,点击增加年龄 */
Button("双向数据"+this.age)
.type(ButtonType.Normal)
.borderRadius(10)
.onClick(()=>{
this.age=this.age+1
})
}
}
}
总结
通过本次学习大家可以掌握基础事件和修饰器,大家可以通过上面案例代码进行实操学习