鸿蒙NEXT开发浅进阶到精通13:鸿蒙开发项目中遇到的问题及解决笔记04

写在前面

一晃又到了下旬,前几天发的工资交了房租和信用卡哈哈,咱们的工作小笔记也够更新一篇了。这里我们主要更新以下知识点和场景,滑动组件套滑动,滚动事件处理、背景色渐变、time时间选择器组件、Navigation路由,传参接参用法、的代码可以对号找解决方式。也可提前收藏后面实战中遇到了也有点印象回来看。

一、鸿蒙中滑动组件套滑动,滚动事件处理如scroll套list

Scroll中嵌套List,在内层滚动容器上添加nestedScroll,根据业务需要调整滚动优先级。注意是放在内层滚动组件的属性下。

ts 复制代码
//在内层滚动容器上添加nestedScroll,根据业务需要调整滚动优先级
.nestedScroll({
  scrollForward: NestedScrollMode.SELF_FIRST,
  scrollBackward: NestedScrollMode.PARENT_FIRST
})

这里是可以拓展的,如list 套swiper,grid等或者反过来互套。

二、背景色渐变

这里并不是很难,只是每次遇到都忘,稍微有点复杂不好记,那我就记下来,忘了记在哪了我就查下文档继续记。

ts 复制代码
.linearGradient({
  angle:136,
  repeating: false, // 渐变颜色是否重复
  colors: [['#FFAA60', 0.0], ['#FF4D32', 1]] // 数组末尾元素占比小于1时满足重复着色效果
})

这里的背景色可以给组件如column、row等容器组件,也可以给文字、图片下使用,一般设计图里会给出比较准确的色值与渐变角度与断点比例。如下图为设计图中wep参考的代码,要注意wep开发中的100%在鸿蒙中是1.50%也就是0.5注意区分。

三、time时间选择器组件--转化返回字符串日期格式 2025-09-01 04-03

日期选择器在开发场景中也比较常见 ,如订酒店,订票,笔记等场景,这里我们是使用DatePicker和TimePicker两个组件组合起来的,大家可以先在这里复制,我后面会封装成三方库直接引用即可。

这里要注意,在使用这个组件时,一般会要求不能选择昨天以前的日期的,所以在DatePicker中,给start设置为当天的日期Date对象即可。我们这次是产品在酒店模块要求这个选择器是用户选择入住酒店的日期与离开酒店的日期之间,供用户选择到店日期与时间。

ts 复制代码
@Builder timeSelectBuilder(){
   Row(){
     DatePicker({
       selected: $$this.selectedDate,
       start: new Date(this.startCheckStr),
end:new Date(this.endCheckStr)
     })
        .onDateChange((value: Date) => {
         this.selectedDate = value;
         console.info('select current date is: ' + value.toString(),'----',this.selectedDate.toDateString()+'----'+this.selectedDate.toTimeString());
       })
       .layoutWeight(1)
     TimePicker({
       selected: this.selectedTime,
     })
       .useMilitaryTime(true)
       .onChange((value: TimePickerResult) => {
         if(value.hour >= 0) {
           this.selectedTime.setHours(value.hour, value.minute);
           console.info('select current date is: ' + JSON.stringify(value),this.selectedTime.toTimeString().slice(0,6),this.selectedTime.toLocaleTimeString());
         }
       })
        .layoutWeight(1)
   }.width('100%')
  .padding(20)
}

getDateFormart(date:Date,time:Date){
  let year = date.getFullYear();
  let month:string = (date.getMonth() + 1).toString()
  if ((date.getMonth() + 1) < 10) {
    month  = '0' + month
  }
  let day:string = date.getDate().toString()
  if (date.getDate() < 10) {
    day  = '0' + day
  }

  return year + '-' + month + '-' + day+' '+time.toTimeString().slice(0,5)
}

四、Navigation路由,传参接参用法

对与这个Navigation路由目前是官方主推的,在多模块或者大点的项目中很好用,而且自带的转场效果可选性也多,主要是不用新建page页面了。传言说是不会担心页面堆栈满了导致崩溃。 具体Navigation路由在整个项目中的配置我们这里不过多叙述,需要一个或几个文章来系统性叙述,一般项目在搭建初期领导组长都已经配好了。你在新业务中跳转和传参接参需要多加注意。

这里分两个大的情况,一种是单模块内跳转路由与跨模块跳转路由,我们先说常见的模块内跳转。

首个页面,使用全局provide来的NavPathStack 实例

ts 复制代码
 @Provide('indexPathStack') pathStack: NavPathStack = new NavPathStack()

其他组件页面(无entry装饰的页面)使用@Consume('indexPathStack') pathStack: NavPathStack; 保证共用一个路由实例

ts 复制代码
 @Consume('indexPathStack') pathStack: NavPathStack; 保证共用

模块内路由

在接参时也有两大习惯性接收方式,可以使用定义好的类型来接收然后,使用类相关属性字段赋值或使用 定义好的对象类型来接收,一般适用于传递过去就是整个对象

ts 复制代码
// 去详情
 this.pathStack.pushPath({ name: "目标页面名", param: item:类型A })

//接
const ParamData = this.pathStack.getParamByName("目标页面名") as 类型A[]
ParamData[0] = hah:类型A

主要是,第二种我们现在的组长比较喜欢用,也可以省一个定义对象类型的代码,那就是Record<string,string>

传参与接参 注意事项:对关键字要细心去c和v不要手写,很大概率出错凹。

好处是不用多余定义类型了, 缺点是用的次数多了会每次都写param,也会出现关键字出现失误不一致,导致赋值失败。适用于路由,emmit 传递数据,不适用在页面渲染

ts 复制代码
//传
// 去详情
let params:Record<string,string>={
  'AaA关键字':this.item.AaA,
  'BaB关键字':this.item.BaB
}
this.pathStack.pushPath({name:'目标页面名',param:params})


//接
const ParamData = this.pathStack.getParamByName("目标页面名") as Record<string,string>[]
if (ParamData && ParamData[0]) {
  let aiah = ParamData[0] as Record<string,string>
  this.orderSN= aiah['ordersn'] //注意关键字是唯一的,错一个大小写导致赋值失败
}

跨模块路由

在跨模块时要注意的不多,因为传参和接参是一样的,我们需要注意的是,跳转方式使用NavPushPathHelper实例,简称helper Navigation路由在这一块很奇怪,使用this.pathStack在开发调试中,使用这种方式也可跳转模块,但编译后不跳转,这 耽误了我们一天的上架进度。其实就是懒了哈哈因为每次跳转都要多创建一次NavPushPathHelper实例,具体如下:

ts 复制代码
@Consume('indexPathStack') pathStack: NavPathStack

const helper: NavPushPathHelper = new NavPushPathHelper(this.pathStack)
helper.pushPath('模块名', { name: '页面名' , param: item.id})

如果你的项目是多模块架构,最好一开始就规范起来用后者,避免打出测试包或者上架审核时出现跳转模块异常的问题,耽误项目进度。

五、 获取设备窗口宽高尺寸

在最基本的鸿蒙开发中我们习惯使用100% 这种百分比作为宽度,因为他是自适应的一种语言,但是遇到一些动态并列或者使用屏幕宽度再减去某个固定值的时候,就要动态获取屏幕宽度了。因为mate60与mate60Pro甚至pro+他们的屏幕宽度 像素也是不同的。在临时调试可以用380或者360vp来计算。

好了我们来看具体如何获取,也是官网cv的只不过在这里你可以直接cv不用翻了

ts 复制代码
 context = this.getUIContext()

window.getLastWindow(this.context.getHostContext()).then((data) => {
  // get window attribute
  let properties = data?.getWindowProperties();
  // Get window width and height
  console.log("windowClass width: " + properties.windowRect.width,px2vp(properties.windowRect.width));
  console.log("windowClass height: " + properties.windowRect.height);
  this.screenWidth = px2vp(properties.windowRect.width)
});

在使用时做个状态变量来接收即可,如果就一个页面用,就放aboutToAppear里,如果项目中多次用到就放在EntryAbility.ets里,再做个持久化储存即可。

写在后面

还是那句话,好记性不如烂笔头吧,勤查勤记,不懂赶紧问。很开心最近更新博客都受到了大家的支持与关注。你们的点赞收藏和交流是 我更新的最大动力。

相关推荐
Nan_Shu_61418 分钟前
学习: Threejs (2)
前端·javascript·学习
G_G#26 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
程序猿追35 分钟前
【鸿蒙PC桌面端实战】从零构建 ArkTS 高性能图像展示器:DevEco Studio 调试与 HDC 命令行验证全流程
华为·harmonyos
@大迁世界42 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路1 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug1 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121381 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架