HarmonyOS开发(七):构建丰富页面

news2024/11/26 15:22:51

1、组件状态管理

1.1、概述

在应用中,界面一般都是动态的。界面会根据不同状态展示不一样的效果。

ArkUI作为一种声明式UI,具有状态驱动UI更新的特点,当用户进行界面交互或有外部事件引起状态改变时,状态的变会会触发组件的自动更新。这个时候南非要通过一个变量来记录状态。当改变态的时候,ArkUI则会自动更新界面中受影响的部分。

ArkUI框架提供了多种管理状态的装饰器来修饰变量,使用这些装饰器修饰的变量即称为状态变量。

在组件范围内传递的状态管理常见场景有如下一些:

场景装饰器
组件内状态管理@State
从父组件单向同步状态到子组件@Prop
与父组件双向同步状态@Link
跨组件层级双向同步状态@Provide和@Consume

注意:在实际应用开发中,应用会根据需要封装数据模型。如果需要观察嵌套类对象属性变化,需要使用@Observed和@ObjectLink装饰器。因为上面表格中所说的装饰器只能观察到对象的第一层属性变化。

1.2、@State:组件内的状态管理

实际开发中由于交互,组件的内容呈现可能产生变化。当需要在组件内使用状态来控制UI的不同呈现方式时,可以使用@State装饰器。

@Entry
@Component
struct StateTest {
  private i: number = 0;
  @State text: string = '';

  build() {
    Row() {
      Column() {
        Button('切换',{type: ButtonType.Capsule, stateEffect: true})
          .width('50%')
          .fontColor(Color.White)
          .fontSize(16)
          .margin({bottom:15})
          .onClick(() => {
            if(this.i % 2 === 0) {
              this.text = 'Harmony OS';
            } else {
              this.text = '鸿蒙系统';
            }
            this.i += 1;
          })
          Text(this.text)
            .fontSize(16)
            .fontWeight(FontWeight.Bold)

      }
      .width('100%')
    }
    .height('100%')
  }
}

上面的例子中,text被修饰为@State,那么它就是一个组件内的状态变量,当这个值变化时,其相应的组件展示也会同时更新。

1.3、@Prop:从父组件单向同步状态

当子组件中的状态依赖于父组件传递过来时,需要使用@Prop装饰器,@Prop修饰的变量可以和其父组件中的状态建立单向同步关系。当父组件中状态变化时,该状态值也会更新至@Prop修饰的变量;对@Prop修饰的变量的修改不会影响其父组件中的状态。

// 子组件 sub.ets
@Component
export struct sub {
  @Prop text: string;

  build(){
    Row(){
      Column(){
        Button('修改text值',{type:ButtonType.Capsule, stateEffect: true})
          .width('50%')
          .margin({bottom:10})
          .fontSize(16)
          .onClick(()=>{
            this.text = 'text在子组件中被修改了'
          })
        Text(this.text)
          .fontSize(16)
      }.height(300)
    }.width('100%')
    .justifyContent(FlexAlign.Center)
  }
}
// 父组件 PropTest.ets
import { sub } from '../components/sub'
@Entry
@Component
struct PropTest {
  @State text:string = '父组件中初始值'
  build() {
    Row() {
      Column() {
        Button('在父组件中修改text',{type:ButtonType.Capsule,stateEffect:true})
          .width('80%')
          .fontSize(16)
          .margin({bottom:10})
          .onClick(()=>{
            this.text = '父组件中修改text的值';
          })
        Text(this.text)
          .fontSize(16)
          .margin({bottom:30})
        sub({text:this.text});
      }
      .width('100%')
    }
    .height('100%')
  }
}

 上面的例子在父组件中传递其text值给到子组件的text,当在父组件中修改这个值的时候子组件中相应的值也会同步变化,但是在子组件中修改这个值时,这个修改的结果不会同步到父组件。

@Prop修饰的变量是从父组件传递值来初始化的,所以在子组件中是不可以做本地初始化的只能接收来自父组件的值。

1.4、@Link:父子组件双向同步状态

如果父组件状态需要相互绑定进行双向同步时,可以使用@Link装饰。父亲组件中用于初始化子组件@Link变量的必须是在父组件中定义的状态变量。

// 子组件
@Component
export struct sub {
  @Link @Watch('OnTextChange') text: string ;
  @State Tip: string = ''

  OnTextChange(){
    if(this.text.indexOf('父组件') >= 0) {
      this.Tip = '使用父组件中的值';
    } else {
      this.Tip = '使用子组件中的值';
    }
  }

  build(){
    Row(){
      Column(){
        Button('修改text值',{type:ButtonType.Capsule, stateEffect: true})
          .width('50%')
          .margin({bottom:10})
          .fontSize(16)
          .onClick(()=>{
            this.text = 'text在子组件中被修改了'
          })
        Text(this.text)
          .fontSize(16)
          .margin({bottom:30})
        Text(`Tip:${this.Tip}`)
          .fontSize(16)

      }.height(300)
    }.width('100%')
    .justifyContent(FlexAlign.Center)
  }
}
// 父组件
import { sub } from '../components/sub'
@Entry
@Component
struct PropTest {
  @State text:string = '父组件中初始值'
  build() {
    Row() {
      Column() {
        Button('在父组件中修改text',{type:ButtonType.Capsule,stateEffect:true})
          .width('80%')
          .fontSize(16)
          .margin({bottom:10})
          .onClick(()=>{
            this.text = '父组件中修改text的值';
          })
        Text(this.text)
          .fontSize(16)
          .margin({bottom:30})
        sub({text:$text});
      }
      .width('100%')
    }
    .height('100%')
  }
}

说明:

1、在子组件中使用@Link修饰时,它就不可以本地化初始化只能通过父组件提供初始值

2、父组件中在给子组件@Link修饰变量进行初始化时需要使用$表示传递的是一个引用

3、@Watch装饰器其内提供的是一个回调函数,它监控变量的变化情况,当发生变化时会触发这个回调函数

1.5、@Provide和@Consume:跨组件层级双向同步状态

它们是用于与后代组件的双向数据同步,应用于数据在多层级之间的传递场景。

@Provide装饰的变量在祖先节点中,可以理解为被“提供”给后代的状态变量

@Consume装饰的变量是在后代组件中,去消费(绑定)祖先节点提供的变量

相关的特点:

  • @Provide装饰的状态变量自动对其所有后代组件可用,开发者无需多次在组件之间传递变量
  • 后代组件通过@Consume去获取@Provide提供的变量,建立@Provide与@Consume之间的双向数据同步,而@State/@Link则不能在多层级父子组件之间传递
  • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,变量类型必须相同
// 通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;

// 通过变量别名绑定
@Provide('a') b: number = 0;
@Consume('a') c: number;
// 后代子组件S2
@Component
export struct S2 {
  @Consume a:number;

  build(){
    Row(){
      Column(){
        Text('S2')
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .margin({bottom:15})
        Text(`a = ${this.a}`)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .margin({bottom:15})
        Button('后代修改a的值',{type:ButtonType.Capsule,stateEffect:true})
          .width('40%')
          .onClick(() => {
            this.a += 10;
          })
      }

    }.width('100%').justifyContent(FlexAlign.Center)
  }

}
// 后代子组件S1
import { S2 } from './S2';
@Component
export struct S1 {
  @Consume a:number;

  build(){
    Row(){
      Column(){
        Text('S1')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .margin({bottom:15})
        Text(`a = ${this.a}`)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .margin({bottom:15})
        Divider()
        S2()
      }


    }.width('100%').justifyContent(FlexAlign.Center)

  }

}
父组件
import { S1 } from '../components/S1'
@Entry
@Component
struct ProvideTest {
  @Provide a: number = 100

  build() {
    Row() {
      Column() {
        Button('祖先修改a的值', {type:ButtonType.Capsule,stateEffect:true})
          .width('50%')
          .margin({bottom:15})
          .onClick(() => {
            this.a += 100;
          })
        Text(`祖先>a = ${this.a}`)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .margin({bottom:20})
        Divider()
        S1()

      }
      .width('100%')
    }
    .height('100%')
  }
}

2、Video组件

2.1、Video件用法介绍

Video组件的接口靛达形式为:

Video(value:{src?: string | Resource, currentProgressRate?:number | string | PlaybackSpeed, previewUri?: string | PixelMap | Resource, controller?: VideoController})

这其中包含四个可选参数:src,currentProgressRate,previewUri和controller。

  • src:视频播放源的路径,支持本地或网络路径,如果是网络地址时,需要在module.json5中申请网络权限。在使用本地资源播放时,可以使用的媒体库管理模块medialibrary来查询公共媒体库中的视频文件。
  • currentProgressRate:视频播放倍速,其参数类型是number,取值支持0.75,1.0,1.25,1.75,2.0,默认是.0
  •  previewUri:表示视频未播放时的预览图片路径
  • controller:表示视频控制器

注意:支持的视频格式:mp4,mkv,webm,TS

2.2、Video组件属性

Video支持组件的尺寸设置、位置设置等通用属性外,Video还支持是否静音、是否自动播放、控制栏是否显示、视频显示模式及单个视频是否循环播放五个私有属性。

muted:参数类型为boolean,表示是否静音,默认值是false

autoPlay:参数类型为boolean,表示是否自动播放,默认值是false

controls:参数类型为boolean,控制视频播放的控制栏是否显示,默认值是true

objectFit:参数类型为ImageFit,设置视频显示模式。默认值是Cover

objectFit中显示模式可选值有:Contain,Cover,Auto,Fill,ScaleDown,None

默认情况一使用Cover(保持宽高比进行缩小或放大,使用图片两边都大于或等于显示边界)

loop:参数类型为boolean,控制单个视频是否循环播放。默认值是false

2.3、Video组件回调事件

事件名称功能描述
onStart(event:() => void)播放时触发这个事件
onPause(event:()=> void)暂停时触发这个事件
onFinish(event:()=> void)播放结束时触发这个事件
onError(event:()=> void)播放失败时触发这个事件
onPrepared(callback:(event?:{duration:number}) => void)视频准备完成时触发这个事件,通过duration可以获取视频时长s
onSeeking(callback:(event?:{time:number}) => void)操作进度条过程时上报时间信息,单位为s
onSeeked(callback:(event?:{time:number}) => void)操作进度条完成后上报时间信息,单位为s
onUpdate(callback:(event?:{time:number}) => void)播放进度变化时触发这个事件,单位为s,更新时间间隔为250ms
onFullscreenChange(callback:(event?:{fullscreen:boolean}) => void)在全屏和非全屏播放状态之间切换时触发这个事件

2.4、自定义控制器

Video组件的原生控制器样式相对固定,当需要对其做一些特殊的显示时则可能无法满足,此时则可以自下义控制器。

可以使用Row容器实现整理体的布局,Text组件来显示起始时间和视频总时长,最后通过Slider组件来实现视频进度条的效果

@Component
export struct VidoSlider {
    ...
    
    build() {
        Row(...) {
            Image(...)
            Text(...)
            Slider(...)
            Text(...)
        }

    ...
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1255047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【企业微信连接问题】

1、个人可以创建企业微信的企业账号么? 答:可以的,只是没法认证。不过基础的功能还是有的。 注册步骤:企业微信注册步骤 2、集简云链接企业微信,在授权之后,找不到集简云怎么办? 答&#xff1a…

美化wordpress复制文章内容弹出版权提示框的源码代码

通过SweetAlert美化的提示框 将下面代码添加到当前主题模板函数functions.php文件最后即可&#xff1a; function zm_copyright_tips() { echo <link rel"stylesheet" type"text/css" rel"external nofollow" target"_blank" href…

人力资源管理后台 === 权限应用

目录 1.权限应用-拆分静态路由-动态路由 2.权限应用-根据用户权限添加动态路由 3.权限应用-根据权限显示左侧菜单 4.权限应用-退出登录重置路由 5.权限应用-功能权限-按钮权限标识 6.权限应用-自定义指令应用功能权限 7.其他模块-集成 8.首页-基本结构和数字滚动 9.首页…

编译器设计03-后端概述

后端处理概述 后端处理&#xff1a;中间代码生成&#xff0c;目标代码生成&#xff0c;贯穿各个阶段的优化。 后端处理犹如得出中文文章&#xff0c;当阅读完英语文章后&#xff0c;你的脑海中就有清晰的“中间代码”了&#xff0c;想写作的时候就心中有数&#xff0c;核心论…

Sringboot3 讲解

文章目录 前言一、Springboot快速入门1.1 实例1.2 总结&#xff1a;1.2.1 什么是starter启动器1.2.2 SpringBootApplication注解的功效 二、springboot3 统一配置文件1.概述2、属性配置文件使用简单案例3、yaml配置介绍和说明4、批量配置文件的读取5、多环境配置和激活 三、spr…

vue页面表单提交时如何做校验

我们在做新增的时候&#xff0c;新增对话框是要加必填校验的&#xff0c;否则就可能会加空数据或者会产生sql的报错。那么这个校验是如何加的呢&#xff1f;下面我们来说一下。 文章目录 一、必填校验1.1 给form表单绑定一个:rules校验规则&#xff0c;给每个item加上一个prop…

17.找出1000之内的所有完数。

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为循环结构编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 一个数如果恰好等于它的因子之和&#xff0c;这个数就称为“完数”。例如&#xff0c;⑥的因子为1、2、3&#xff0c;而…

创建可以离线打包开发的uniapp H5项目

安装node环境 略 安装vue脚手架&#xff0c;在线 npm install -g vue/cli PS&#xff1a;vue-cli已进入维护模式&#xff0c;vue3最新脚手架使用npm init vuelatest安装&#xff0c;安装后使用create-vue替换vue指令&#xff0c;create-vue底层使用vite提升前端开发效率&…

【c++文件】

C是一种面向对象的编程语言&#xff0c;它广泛应用于各个领域&#xff0c;如游戏开发、嵌入式系统、操作系统等。在C编程中&#xff0c;文件操作是一项非常重要的技能。本文将介绍C文件操作的基本知识以及一些有趣的应用&#xff0c;带领大家一起探索C文件操作的魅力。 一、C文…

autojs-练手-简单的视频号点赞(初阶版)

注释很详细&#xff0c;直接上代码&#xff08;简单的练手实践&#xff0c;仅供参考&#xff09; //设置点赞次数 var num50; //等待权限授予 auto.waitFor(); //进入点赞流程 while(num!0) {//先向下滑一个视频scrollDown();//使用auto.js找到点赞控件的id&#xff08;每个人不…

VBA技术资料MF86:将PPT文件批量另存为PDF文件

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

『OPEN3D』1.8 点云的配准理论

点云的配准是将不同的3D点云对齐成一个完成的点云模型&#xff1b;配准的目标是找到两帧点云之间的相对旋转&#xff08;rotation&#xff09;与平移&#xff08;translation&#xff09;&#xff0c;使得两份点云中有重叠的区域能够完好拼接。 点云配准示例图&#xff08;来自…

数据库基础教程之数据库的创建(一)

双击打开Navicat&#xff0c;点击&#xff1a;文件-》新建连接-》PostgreSQL 在下图新建连接中输入各参数&#xff0c;然后点击&#xff1a;连接测试&#xff0c;连接成功后再点击确定。 点击新建数据库 数据库设置如下&#xff1a;

10分钟构建本地知识库,让 ChatGPT 更加懂你

大家好&#xff0c;本文将从零开始构建本地知识库&#xff0c;从而辅助 ChatGPT 基于知识库内容生成回答。 这里再重复下部分核心观点&#xff1a; 向量&#xff1a;将人类的语言&#xff08;文字、图片、视频等&#xff09;转换为计算机可识别的语言&#xff08;数组&#xf…

ios开发 之 网络通信

第一节&#xff1a;URL、http 简介 运营商提供的DNS服务器&#xff08;有可能挂&#xff0c;所以有时候通过ip可以打开&#xff0c;通过域名不可以访问&#xff09;逐级递增请求&#xff0c;解析域名 google 提供的dns服务器8.8.8.8 编码怎么来的&#xff1a; 最开始是ASCII码…

【Web】/proc利用相关例题wp

先贴一篇文章一起学习一下 [CTF]proc目录的应用 - CodeAntenna ①[HDCTF 2023]YamiYami 点击Read somethings直接跳转到了百度 从url中发现存在任意文件读取&#xff0c;因为不知道flag在哪&#xff0c;所以考虑读环境变量 payload: ?urlfile:///proc/1/environ 拿到fla…

系列十七、各种各样的bean

一、Spring bean 1.1、概述 一句话&#xff0c;被Spring容器管理的bean就是Spring bean。 二、Java bean VS Spring bean 2.1、概述 Java bean是程序员自己new 出来的&#xff0c;Spring bean是Spring工厂创建出来的。 三、配置bean的方式 3.1、概述 所谓配置bean&#xff0…

【精选必读】MyBatis关联查询及注解开发

文章目录 MyBatis关联查询MyBatis一对一关联查询创建持久层接口创建映射文件配置文件注册映射文件测试一对一关联查询 MyBatis一对多关联查询创建持久层接口创建映射文件测试一对多关联查询 MyBatis多对多关联查询创建持久层接口创建映射文件测试多对多关联查询 MyBatis分解式查…

性能测试必看系列之Jmeter:硬件性能监控指标

硬件性能监控指标 一、性能监控初步介绍 性能测试的主要目标 1.在当前的服务器配置情况&#xff0c;最大的用户数 2.平均响应时间ART&#xff0c;找出时间较长的业务 3.每秒事务数TPS&#xff0c;服务器的处理能力 性能测试涉及的内容 1.客户端性能测试&#xff1a;web前…

一. BEV感知算法介绍

目录 前言1. BEV感知算法的概念2. BEV感知算法数据形式3. BEV开源数据集介绍3.1 KITTI数据集3.2 nuScenes数据集 4. BEV感知方法分类4.1 纯点云方案4.2 纯视觉方案4.3 多模态方案 5. BEV感知算法的优劣6. BEV感知算法的应用介绍7. 课程框架介绍与配置总结下载链接参考 前言 自动…