社区编辑申请
注册/登录
HarmonyOS ArkUI之自定义组件侧滑菜单(JS)
开发 前端 OpenHarmony
鸿蒙这次API7更新除了新增TS声明式开发之外,还有JS开发也增加了很多API,JS开发自定义组件越来越方便了。本文介绍最新出的插槽用法,实现侧滑菜单、支持两种风格、支持快速滑动打开关闭。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

鸿蒙这次API7更新除了新增TS声明式开发之外,还有JS开发也增加了很多API,JS开发自定义组件越来越方便了。

本项目基于ArkUI中JS扩展的类Web开发范式,关于语法和概念直接看官网官方文档地址:

基于JS扩展的类Web开发范式1 基于JS扩展的类Web开发范式2

本文介绍最新出的插槽用法,实现侧滑菜单、支持两种风格、支持快速滑动打开关闭。

ArKUI系列文章

  • 【HarmonyOS ArkUI之仿微信朋友圈图片预览】
  • 【HarmonyOS ArkUI之仿微信图片选择】
  • 【HarmonyOS ArkUI之自定义组件侧滑菜单(JS)】

效果演示

风格一:内容页在菜单上面风格二:内容页在菜单下面

HarmonyOS ArkUI之自定义组件侧滑菜单(JS)-鸿蒙HarmonyOS技术社区HarmonyOS ArkUI之自定义组件侧滑菜单(JS)-鸿蒙HarmonyOS技术社区

主要知识点

触摸事件、自定义组件父子组件传递参数、api=7新出的slot插槽

实现思路

自定义组件的逻辑都在此目录下:entry/js/default/pages/drawer

主要使用onTouch相关事件,滑动改变菜单布局或内容布局的left偏移量,手指抬起使用动画完成偏移量

1、onTouch相关事件

只贴出了关键代码

  1.  /** 
  2.    * 触摸按下 
  3.    */ 
  4.   onTouchStart(event) { 
  5.       // 记录首次按下的x坐标 
  6.       this.pressX = event.touches[0].localX 
  7.       // 记录上次的x坐标 
  8.       this.lastX = this.pressX 
  9. ..... 
  10.   }, 
  11.   /** 
  12.    * 触摸移动 
  13.    */ 
  14.   onTouchMove(event) { 
  15.     // 当前x坐标 
  16.       let localX = event.touches[0].localX 
  17.       // 计算与上次的x坐标的偏移量 
  18.       let offsetX = this.lastX - localX; 
  19.       // 记录上次的x坐标 
  20.       this.lastX = localX 
  21.       // 累计偏移量 
  22.       this.offsetLeft -= offsetX 
  23.        
  24.       // 设置偏移量的范围 
  25.       ..... 
  26.   } 
  27.  
  28. ** 
  29.    * 触摸抬起 
  30.    */ 
  31.   onTouchEnd(event) { 
  32.        
  33.       ...... 
  34.        
  35.       // 手指抬起,根据情况,判断toX的值,也就是判断关闭或开启菜单的情况 
  36.       // 当移动偏移量大于菜单一半宽度,完全打开菜单,否则反之 
  37.       if (this.offsetLeft > this.menuWidth / 2) { 
  38.           toX = this.menuWidth 
  39.       } else { 
  40.           toX = 0 
  41.       } 
  42.        
  43.       ...... 
  44.        
  45.       // 开启动画 
  46.         this.startAnimator(toX)       
  47.        
  48.   } 
  49.   /** 
  50.    * 开启动画 
  51.    */ 
  52.   startAnimator(toX) { 
  53.       // 设置动画参数 
  54.       let options = { 
  55.           duration: ANIMATOR_DURATION, // 持续时长 
  56.           fill: 'forwards', // 启停模式:保留在动画结束状态 
  57.           begin: this.offsetLeft, // 起始值 
  58.           end: toX // 结束值 
  59.       }; 
  60.       // 更新动画参数 
  61.       this.animator.update(options) 
  62.       // 监听动画值变化事件 
  63.       this.animator.onframe = (value) => { 
  64.           this.offsetLeft = value 
  65.           this.changeMenuOffsetLeft() 
  66.       } 
  67.       // 开启动画 
  68.       this.animator.play() 
  69.   }, 

2、showStyle

0 第一种样式下,解决设置z-index之后菜单界面在内容下面,但点击事件却还在内容上面的问题。

初始化设置left偏移量

动画结束,判断菜单是否关闭,关闭直接设置菜单偏移量为负的菜单宽度

注意:目前使用插槽之后,预览器不走生命周期方法:onShow。

  1. export default { 
  2.     // 使用外部传入 
  3.     props: ['showStyle'],// 显示样式:0菜单在下面,1菜单在上面 
  4.       ...... 
  5.   } 
  6. ** 
  7.    * 界面显示 
  8.    */ 
  9.   onShow() { 
  10.       ..... 
  11.     // 设置菜单偏移量为负的菜单宽度,为了解决z-index设置后,菜单界面到内容下面, 
  12.       // 事件还停留到内容上面,导致点击菜单区域,响应的还是菜单点击事件 
  13.       this.menuOffsetLeft = -this.menuWidth 
  14.   } 

3、使用具名插槽封装

  1. <div id="drawer-container" class="drawer-container" on:touchstart="onTouchStart" 
  2.      on:touchmove="onTouchMove" on:touchend="onTouchEnd"
  3.  
  4.     <div class="drawer-content" style="left : {{ showStyle == 0 ? offsetLeft : 0 }} px; 
  5.             z-index : {{ zIndexContent }};" on:click="closeMenu"> 
  6.  
  7.     <!--具名插槽,根据名称加入对应的插槽中--> 
  8.         <slot name="content"></slot> 
  9.          
  10.     </div> 
  11.  
  12.     <stack class="drawer-menu" style="z-index : {{ zIndexMenu }};"
  13.         <div class="drawer-menu-background" style="opacity : {{ menuBgOpacity }};"></div> 
  14.         <div style="width : {{ menuWidth }} px; height : 100%; 
  15.                 left : {{ menuOffsetLeft }} px;" on:click="clickMenu"> 
  16.  
  17.         <!--具名插槽,根据名称加入对应的插槽中--> 
  18.             <slot name="menu"></slot> 
  19.  
  20.         </div> 
  21.     </stack> 
  22.  
  23. </div> 

4、index页面使用

  1. <!--引入自定义组件--> 
  2. <element name='drawer' src='../drawer/drawer.hml'></element> 
  3. <div class="container"
  4.     <!--通过传值设置样式--> 
  5.     <drawer show-style="0"
  6.         <!--根据名称加入对应的插槽中--> 
  7.         <div slot='content' class="content-layout"
  8.             <div class="title-bar"
  9.                 <text>主页</text> 
  10.             </div> 
  11.             <div class="mainpage-content"
  12.                 <text class="content1">我是内容页面</text> 
  13.                 <text class="content2">V1.0.0</text> 
  14.                 <text class="content2">梁迪迪</text> 
  15.             </div> 
  16.         </div> 
  17.  
  18.         <div slot='menu' class="menu-layout"
  19.             <div class="my-info"
  20.                 <image src="common/images/head_photo.png"></image> 
  21.                 <text>登录 | 注册</text> 
  22.             </div> 
  23.             <div class="menu-content"
  24.                 <div for="{{ listMenu }}" tid="{{ $item.id }}" on:click="menuSkip({{ $item.name }})"
  25.                     <image src="{{ $item.icon }}"></image> 
  26.                     <text>{{ $item.name }}</text> 
  27.                 </div> 
  28.             </div> 
  29.         </div> 
  30.     </drawer> 
  31. </div> 

结尾

每天进步一点点、需要付出努力亿点点。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-07-06 20:24:08

ArkUI计时组件

2022-07-13 16:24:12

ArkUI(JS)打地鼠游戏

2022-05-23 10:53:54

canvas柱状图鸿蒙

2022-07-15 16:45:35

slider滑块组件鸿蒙

2022-05-20 14:34:20

list组件鸿蒙操作系统

2021-11-26 15:31:43

2022-07-26 14:40:42

ArkUIJS

2021-12-21 15:22:22

2022-02-16 15:25:31

JS代码Canvas鸿蒙

2022-04-24 15:17:56

鸿蒙操作系统

2021-10-14 15:14:36

2021-08-12 15:01:09

同话题下的热门内容

Java 服务 Docker 容器化优秀实践程序员不得不知道的 API 接口常识TestOps完全手册:工作流、生命周期、团队和流程11个 ES2022(ES13)中惊人的 JavaScript 新特性不要在 Python 中使用循环,这些方法其实更棒!使用 Vite 和 TypeScript 带你从零打造一个属于自己的 Vue3 组件库你需要知道的TypeScript高级类型Hooks时代,如何写出高质量的react和vue组件?

编辑推荐

太厉害了,终于有人能把TCP/IP协议讲的明明白白了!牛人5次面试腾讯不成功的经验HBase原理–所有Region切分的细节都在这里了Javascript如何监听页面刷新和关闭事件如何搭建一个HTTPS服务端
我收藏的内容
点赞
收藏

51CTO技术栈公众号