最近使用nvue开发手机app,踩了不少坑,虽然大部分都勉强解决了,办法十分邪道,也仍有部分问题无解,特此整理公布,以赠后来者。
打包相关
1.关于midbutton高度对齐的问题。
答: 因原生平台差异,对图片型的midbutton设置高度,在安卓和苹果端可能产生无法垂直对齐的问题,又因为pages.json并未提供条件编译功能,建议手动校准修改两端高度,分别打包安卓和苹果端。
有解的问题
1.关于nvue的v-show能力。
答: 因 nvue 渲染层采用 weex,底层对元素的渲染机制,容易造成切换元素时的抖动现象。插件市场有相关 weex-v-show 插件,或者使用动态设置宽度和 opacity 达到类似效果。
2.关于input组件动态设置placeholder样式。
答: input组件可通过设置placeholder-style和placeholder-class属性设置placeholder的样式,但仅初次设置有效,无法动态改变,weex文档里提供了placeholder-color属性,可以通过css动态设置,改变placeholder的颜色;但是nvue编译器会对此属性抛出警告,在意者可通过写成行内样式进行规避。
3.关于overflow属性切换。
答: 因安卓端只支持overflow:hidden,此属性几乎无用,但weex文档里提到过只有同时满足以下四个条件,父view才会裁剪子view:
1.父view是 div, a, cell, refresh 或 loading
2.系统版本是 Android 4.3 或更高。
3.系统版本不是 Andorid 7.0。
4.父 view 没有 background-image 属性或系统版本是 Android 5.0 或更高。
这也意味着,似乎可以通过打破上述的任一条件限制,以此间接实现overflow:visible的效果?此想法仅笔者猜测,暂未实践。
4.关于subNvue的相关问题。
答: 可参考此回答,https://ask.dcloud.net.cn/article/41670?notification_id-1540939__item_id-65695。
5.关于swipera-action组件。
答: uni-ui提供的swipera-action在app端表现不佳,经常有异常抖动的问题,笔者在实践中采用了fui-swipe-action,当clickClose属性设置为false时,体验良好,基本满足需求。如果clickClose设置为true,也会出现和uni-ui类似的问题,猜测系bindingX的编写问题。
6.关于swiper组件。
答: 因底层限制,且nvue几乎不再维护,swiper相关的问题几乎无解,如设置动画时长或关闭动画等,笔者只能提出两种未经实践的想法,第一种是修改uniapp源码,手动添加weex的forbid-slide-animation属性;第二种即通过bindingX,自己实现一个swiper组件。
7.关于同行text设置不同样式的问题。
答: 因nvue不支持text嵌套,且仅有text组件能设置文字样式,此问题几乎无解,如果你没有文字换行的需求,可通过拆分文本,塞入不同的text并设置不同的样式;如果你需要换行,笔者的实践办法是更换为rich-text组件,数组型的nodes属性可以完美解决此类问题,虽然编写元素数组比较麻烦,但好在有效。
8.关于list和waterfall的长列表问题。
答: 正常使用几乎不存在性能问题,唯一的优化方向,可能就是当cell包含图片时,考虑优化图片大小减少内存消耗,另外cell组件的delete-animation="default"和insert-animation="default"需要明写,否则不会有默认的动画效果。
关于长列表内部的refresh和loading组件,refresh组件可以正常使用,几乎不存在兼容性问题,但loading组件需要分情况处理:
- 对于ios端,当列表元素长度大于1屏时,可以正常使用loading组件,当列表元素不足1屏时,会出现loading组件停留在列表顶部的Bug,建议在此种情况下,使用列表内置的header组件模拟loading(注意把header组件放置在列表底部),达到类似效果,当元素超过1屏后,再切换。
- 对于安卓端普通长列表,可以正常使用loading组件。
- 对于安卓端嵌套长列表,loading组件无法正常渲染,此种情况同样建议采用header组件模拟loading(注意把header组件放置在列表底部),基本可以达到比较良好的效果。
另外注意,无论是refresh还是Loading,其内置的loading-indicator组件都不建议使用,因其动画效果几乎不存在,考虑使用第三方图标替代。
9.底部输入区和键盘弹出的无缝动画协调问题。
答: 大部分App都会有留言或评论功能,往往需要从底部弹出自定义的留言区域,然而手机软键盘也会同时弹出,如何协同两者弹出时的动画效果,也需要分情况考虑,经观察,大部分app在ios端往往可以做到比较完美的效果,即软键盘从底部弹出时,留言区会顺势被顶起,整个过程流畅且无缝,观感十分好;而安卓端则没那么完美,软键盘和留言区的弹出动画往往是分先后完成的。
关于实际编码中如何解决这个问题,如果是原生编码,可以通过获取软键盘的属性来解决,uniapp做不到这点,只能曲线救国:
- 在ios端,考虑以subNvue来渲染弹出层,手动focus弹出层中的输入组件,并将adjust-position设置为true,弹出的键盘会把整个subNvue弹起,整个过程流畅无缝,效果很好,类似的办法也可以考虑使用透明的新页面,不过如何控制路由和如何隐藏都是个问题,subNvue会简单许多,另外第一次弹出的时候会稍有卡顿,这一点在其余app上也经常出现, 属于正常现象,后续的弹出就很正常了。
- 在安卓端,如上面所说的,暂时没有无缝弹出的办法,只能通过dom控制动画去尽量贴合键盘的弹起速度,关于这点不必花大力气去模拟贴合,毕竟做不到完美,能用即可。
10.关于安卓机进入新页面,image组件会出现闪白问题。
答: 因weex底层渲染机制,此问题无法直接解决,哪怕更换成Img组件一样会有此问题,只能通过两种方式缓解:
- 添加骨架图,等图片触发load事件后再显示。
- 在能计算出图片出现的位置和大小的情况下,可以考虑使用plus.nativeObj.view预先渲染图片,经笔者测试,此方式不会有延迟和闪白问题,结合startAnimation方法,几乎可以做到和页面进入动画无缝贴合,等到页面完全进入后,再关闭view即可。
11.关于如何在nvue绘制三角形元素。
答: 传统web绘制三角形的办法基于border做文章,但nvue支持的css属性有限,无法直接解决,笔者的办法是渲染两个元素,将底层元素旋转,用上层元素遮盖底层元素,以此来达到模拟三角形的效果。
暂时无解的问题
1.image 组件 mode 设置为 aspectFit 的时候,如果给 Image 加上 border-radius,安卓端图片显示会出现异常拉伸,此问题系框架底层bug,目前无解决办法。
2.原生配置的tabbar,点击切换tabbar后如何触发动画特效问题,笔者有两者思路,一种是全局只有一个页面,即单页面富应用,nvue自行渲染底部tabbar,不过这种方案应该只适用小型项目;另一种则是结合gif图片,笔者看到网络上有提到,gif可设置只循环一次,具体效果暂未实践,留待后续验证。