|
|
|
|
公众号矩阵

从微信小程序到鸿蒙JS开发-menu&toast&dialog

文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz

作者:Chris来源:鸿蒙社区|2021-02-22 14:56

 

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

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

https://harmonyos.51cto.com/#zz

1、menu弹出菜单

这是微信小程序没有的一个组件,提供了一个可唤起的轻量级弹出菜单。menu的子组件为option。

  1. <menu id="userMenu" onselected="menuSelect"
  2.     <option value="login">登录</option
  3.     <option value="register">注册</option
  4. </menu> 

在hml中写好菜单,但这时启动app是不会显示出来的,且不会占用任何页面空间。

menu需要在方法中被唤起,因此需要设置id属性。这里通过点击“点击登录/注册“文本框唤起菜单:

  1. <text if="{{ !userInfo }}" onclick="showUserMenu" class="info_hint"
  2.     点击登录/注册 
  3. </text> 

  1. showUserMenu() { 
  2.     this.$element("userMenu").show(); 

使用无参的show()方法,菜单在页面的左上角被唤起弹出。

show方法还有一个重载方法,可以设置菜单弹出的x轴和y轴偏移量。x和y需要给数值类型,单位为px。

  1. showUserMenu() { 
  2.     this.$element("userMenu").show({ 
  3.         x: 100, 
  4.         y: 100 
  5.     }); 

菜单项的选中事件通过onselect属性绑定,event.value即为选中的option的value属性。

  1. menuSelect(event) { 
  2.     let value = event.value; 
  3.     prompt.showToast({ 
  4.         message: "点击菜单项的值为" + value, 
  5.         duration: 3000 
  6.     }) 

option一定要设置value属性,否则编译不通过。value重复倒是不会报错,但这样无法判断选中了哪一个菜单项,不建议。


2、Toast提示框

鸿蒙js开发模式至今无法通过console.log()等方法打印日志(mac系统如此),但在写程序时不免要进行调试,提示框就是一种很好的方法。

在js文件中引入prompt模块:

  1. import prompt from '@system.prompt'

调用prompt.showToast()弹出提示框:

  1. prompt.showToast({ 
  2.     message: "提示信息"
  3.     duration: 3000 
  4. }); 

这个方法只能传递message和duration两个参数,弹出位置是在页面接近最下方中间位置,而且字有点小。

源码注释中说明,duration取值是1500到10000,如果不在范围中会自动更改为边界值。

再看看微信小程序的Toast,使用wx.showToast弹出。

  1. wx.showToast({ 
  2.     title: '提示信息'
  3.     duration: 3000 
  4. }) 

弹出位置在页面正中,且可以切换预置,或自定义图标。

  1. wx.showToast({ 
  2.     title: '常回家看看'
  3.     duration: 3000, 
  4.     icon: 'none'
  5.     image: "/icon/index1.png" 
  6. }) 

就是这个图标位置怪怪的,但个人感觉这种提示弹窗更加明显,可扩展性也更强。

3、prompt模块的对话框dialog

需要用户确认操作的功能十分常用,比如是否删除,是否下单等。在微信小程序中采用的是wx.showModal(),弹窗内容、按钮内容和颜色都可以自定义,事件在success函数中进行捕获:

  1. wx.showModal({ 
  2.   title: "提示"
  3.   content: "确认删除吗?"
  4.   confirmColor: "#e20a0b"
  5.   confirmText: "对,删了它"
  6.   cancelColor: "#777777"
  7.   cancelText: "再考虑一下"
  8.   success: res => { 
  9.     if(res.confirm) { 
  10.       console.log("删除成功!"); 
  11.     } else if(res.cancel) { 
  12.       console.log("取消删除操作。"
  13.     } 
  14.   } 
  15. }) 

在鸿蒙中,prompt模块的showDialog()方法提供了弹出对话框:

  1. prompt.showDialog({ 
  2.      title: "操作提示"
  3.      message: "确认删除吗?"
  4.      buttons: [ 
  5.          { 
  6.              text: "我要删除"
  7.              color: "#e20a0b" 
  8.          }, 
  9.          { 
  10.              text: "取消操作"
  11.              color: "#777777" 
  12.          } 
  13.      ], 
  14.      success: res => { 
  15.          prompt.showToast({ 
  16.              message: "点击了第" + res.index + "个按钮" 
  17.          }) 
  18.      } 
  19.  }) 

对话框也是在底部弹出的,且按钮可以自行定义。点击按钮后,success方法会获取按钮的索引值,根据索引进行业务逻辑的编写。

想要设置三个按钮也是可以的,这个功能微信小程序的showModal()是没有的。

  1. prompt.showDialog({ 
  2.         title: "操作提示"
  3.         message: "确认删除吗?"
  4.         buttons: [ 
  5.             { 
  6.                 text: "我要删除"
  7.                 color: "#e20a0b" 
  8.             }, 
  9.             { 
  10.                 text: "取消操作"
  11.                 color: "#777777" 
  12.             }, 
  13.             { 
  14.                 text: "附加按钮"
  15.                 color: "#333333" 
  16.             } 
  17.         ], 
  18.         success: res => { 
  19.             prompt.showToast({ 
  20.                 message: "点击了第" + res.index + "个按钮" 
  21.             }) 
  22.         } 
  23.     }) 

4、dialog对话框组件

prompt.showDialog()只能弹出具有提示文字和按钮的对话框,如果需要更丰富的模态对话框功能,鸿蒙还提供了dialog组件,这个组件在微信小程序中也是没有的。和menu一样,写在hml中的dialog并不会显示,也不会占用页面空间,需要通过id在方法中被唤起。

  1. <dialog id="loginDialog"
  2.     <div class="loginDialog"
  3.         <div class="formItem"
  4.             <image src="{{ phone ? (imgUrl + 'phone.png') : (imgUrl + 'phone1.png') }}"></image> 
  5.             <input id="phoneInput" type="number" placeholder="请输入手机号" onchange="inputPhone"></input> 
  6.         </div> 
  7.         <div class="formItem"
  8.             <image src="{{ pwd ? (imgUrl + 'password.png') : (imgUrl + 'password1.png') }}"></image> 
  9.             <input id="pwdInput" type="password" placeholder="请输入密码" onchange="inputPwd"></input> 
  10.         </div> 
  11.         <button class="inputBtn" onclick="login">登录</button> 
  12.     </div> 
  13. </dialog> 

这里需注意,官方文档中说的“支持单个子组件”的意思是,dialog中只能有一个直接子组件,即需要用一个div将内容套起来。

 

同样地,根据id找到元素,使用show()方法唤起对话框。对话框的show()方法无重载,会在页面底部弹出。dialog的大小取决于子组件div的大小,div给样式即可。

  1. menuSelect(event) { 
  2.      let value = event.value; 
  3.      if ("login" == value) { 
  4.          this.phone = ""
  5.          this.pwd = ""
  6.          this.$element("loginDialog").show(); 
  7.      } else if ("register" == value) { 
  8.          this.phone = ""
  9.          this.pwd = ""
  10.          this.$element("registerDialog").show(); 
  11.      } 
  12.  }, 

可用close()方法关闭它。

  1. this.$element("registerDialog").close(); 

附上本页面的代码,后台功能自己搭建了Spring Boot服务器进行交互。下篇将讲解表单组件:

  1. <!-- 我的 --> 
  2.   <div class="myPage"
  3.       <div class="userInfo"
  4.           <image src="{{ userInfo && userInfo.avatar != '0' ? userInfo.avatar : (imgUrl + 'user.png')}}"></image> 
  5.           <div class="info_desc"
  6.               <text if="{{ !userInfo }}" onclick="showUserMenu" class="info_hint"
  7.                   点击登录/注册 
  8.               </text> 
  9.               <text if="{{ userInfo }}" class="info_name"
  10.                   {{ userInfo.nickname ? userInfo.nickname : userInfo.username }} 
  11.               </text> 
  12.               <text if="{{ userInfo }}" class="info_detail"
  13.                   {{ userInfo.age }}  {{ userInfo.gender == 1 ? '男' : (userInfo.gender == 2 ? '女' : '性别保密') }} 
  14.               </text> 
  15.           </div> 
  16.       </div> 
  17.       <menu id="userMenu" onselected="menuSelect"
  18.           <option value="login">登录</option
  19.           <option value="register">注册</option
  20.       </menu> 
  21.       <dialog id="loginDialog"
  22.           <div class="loginDialog"
  23.               <div class="formItem"
  24.                   <image src="{{ phone ? (imgUrl + 'phone.png') : (imgUrl + 'phone1.png') }}"></image> 
  25.                   <input id="phoneInput" type="number" placeholder="请输入手机号" onchange="inputPhone"></input> 
  26.               </div> 
  27.               <div class="formItem"
  28.                   <image src="{{ pwd ? (imgUrl + 'password.png') : (imgUrl + 'password1.png') }}"></image> 
  29.                   <input id="pwdInput" type="password" placeholder="请输入密码" onchange="inputPwd"></input> 
  30.               </div> 
  31.               <button class="inputBtn" onclick="login">登录</button> 
  32.           </div> 
  33.       </dialog> 
  34.   </div> 
  35.   <!-- 我的end --> 

css:

  1. /*我的*/ 
  2. .userInfo { 
  3.     width: 92%; 
  4.     height: 240px; 
  5.     margin: 20px 0 20px 0; 
  6.     border-radius: 30px; 
  7.     box-shadow: 5px 5px 15px #bbbbbb; 
  8.     background-color: #eeeeee; 
  9.     display: flex; 
  10.     align-items: center; 
  11. .userInfo>image { 
  12.     margin: 0 40px 0 40px; 
  13.     width: 160px; 
  14.     height: 160px; 
  15.     border-radius: 90px; 
  16.     object-fit: contain; 
  17. .info_desc { 
  18.     height: 200px; 
  19.     margin-right: 20px; 
  20.     flex: 1; 
  21.     display: flex; 
  22.     flex-direction: column
  23.     justify-content: center; 
  24. .info_hint { 
  25.     font-size: 48px; 
  26.     font-weight: bold; 
  27.     color: #333333; 
  28. .info_name { 
  29.     font-size: 40px; 
  30.     font-weight: 600; 
  31.     height: 100px; 
  32.     color: #333333; 
  33. .info_detail { 
  34.     font-size: 34px; 
  35.     color: #666666; 
  36. .loginDialog { 
  37.     width: 80%; 
  38.     height: 400px; 
  39.     display: flex; 
  40.     flex-direction: column
  41.     align-items: center; 
  42.     justify-content: center; 
  43. .formItem { 
  44.     width: 100%; 
  45.     height: 100px; 
  46.     display: flex; 
  47.     align-items: center; 
  48.     justify-content: space-between
  49.     margin-bottom: 20px; 
  50. .formItem>image { 
  51.     width: 70px; 
  52.     height: 70px; 
  53.     margin: 0 10px 0 10px; 
  54. input { 
  55.     flex: 1; 
  56. .inputBtn { 
  57.     width: 200px; 
  58.     height: 70px; 

js:(省略data部分)

  1. // 弹出菜单 
  2.  showUserMenu() { 
  3.      this.$element("userMenu").show(); 
  4.  }, 
  5.  // 菜单选中 
  6.  menuSelect(event) { 
  7.      let value = event.value; 
  8.      if ("login" == value) { 
  9.          this.phone = ""
  10.          this.pwd = ""
  11.          this.$element("loginDialog").show(); 
  12.      } else if ("register" == value) { 
  13.          this.phone = ""
  14.          this.pwd = ""
  15.          // this.$element("registerDialog").show(); 
  16.      } 
  17.  }, 
  18.  // 手机号输入框 
  19.  inputPhone(e) { 
  20.      this.phone = e.value; 
  21.  }, 
  22.  // 密码输入框 
  23.  inputPwd(e) { 
  24.      this.pwd = e.value; 
  25.  }, 
  26.  // 登录 
  27.  login() { 
  28.      fetch.fetch({ 
  29.          url: this.url + "/litemall/user/login?phone=" + this.phone + "&pwd=" + this.pwd, 
  30.          responseType: "json"
  31.          success: res => { 
  32.              let data = JSON.parse(res.data); 
  33.              if (0 != data.code) { 
  34.                  prompt.showToast({ 
  35.                      message: data.msg, 
  36.                      duration: 3000 
  37.                  }) 
  38.              } else { 
  39.                  this.userInfo = data.data; 
  40.                  this.$element("loginDialog").close(); 
  41.              } 
  42.          } 
  43.      }) 
  44.  } 

登录成功效果:

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

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

https://harmonyos.51cto.com/#zz

【编辑推荐】

  1. 为什么你总是学不会Python,入门Python的4大陷阱
  2. 厌倦了默认系统字体?这是在Windows 10上进行更改的方法
  3. 5G手机热销之前,要先解决这些问题
  4. 手把手教你用Python爬取百度搜索结果并保存
  5. 揭秘登上2021春晚舞台的黑科技-XR技术
【责任编辑:jianghua TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

数据湖与数据仓库的分析实践攻略

数据湖与数据仓库的分析实践攻略

助力现代化数据管理:数据湖与数据仓库的分析实践攻略
共3章 | 创世达人

6人订阅学习

云原生架构实践

云原生架构实践

新技术引领移动互联网进入急速赛道
共3章 | KaliArch

33人订阅学习

数据中心和VPDN网络建设案例

数据中心和VPDN网络建设案例

漫画+案例
共20章 | 捷哥CCIE

220人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微