抛开软件功能不谈,在交互体验上,打造一款能和原生APP相媲美的微信小程序,是我这样的微信开发者的梦想。想在技术上想实现原生的功能,开发成本是非常巨大的。但感谢微信小程序推出的渲染引擎Skyline,让我可以轻松实现原生app的交互体验。
目前,小程序已上线运行半月,虽有bug,但瑕不掩瑜。如果您对于使用webView开发还是Skyline开发还有疑虑的话,希望以下介绍对于有选择困难症的同学们有所帮助。接下来,我想借助自己开发的小程序,向大家推荐与介绍Skyline渲染引擎(当然也希望向大家推荐我所开发的小程序 -- 「 NONZERO COFFEE 」)。
如有错误或遗漏,欢迎在评论区批评指正,不胜感激。
小程序效果演示
对小程序感兴趣的也可以加我好友讨论技术:
开发文档中对于Skyline的介绍,有以下几个重要的增强特性:worklet 动画、手势系统、自定义路由(预设路由)、共享元素动画。对于他们的使用和说明,我就不过多说明了,具体可以参照:https://mp.weixin.qq.com/s/dRz2PnkwHxYVL2kCexQ7WQ。
接下来我会介绍这些特性在小程序中,是怎么变成我的奇淫巧技,让小程序也可以更加优美。
worklet 动画:丝滑与复杂的页面元素展示
当页面滚动时,我们通常会希望根据页面不同的滚动状态或位置,灵活的展示或改变某些元素的状态,那么借助scroll-view的worklet:onscrollupdate时间和worklet动画可以完美实现效果~
1、展示中可以看到背景图片会随着下拉放大,但是上滑时却是跟随上滑,完美实现不同状态
2、为了优化顾客点单体验,主要菜单栏(点单、外卖、商城)需要在上滑至离开屏幕时,顶部需要弹出备用菜单栏.
以上效果如果通过简单的wx:if判断,那么动画效果势必会很突兀,如果使用worklet 动画的timing()与spring()函数,可以轻松实现动画的流畅效果。
附上简单代码:
这里是置顶的点单菜单栏 这里是页面内容和
onLoad(options) {
// 背景图片的高度和缩放
this.bgimgTop = shared(0)
this.bgimgSca = shared(1)
// 顶部点单栏透明度
this.topfunOp = shared(0)
},
onReady() {
// 背景图片动画监听
this.applyAnimatedStyle('.bgimg', () => {
'worklet'
return {top: `${this.bgimgTop.value}px`,transform:`scale(${this.bgimgSca.value},${this.bgimgSca.value})`}
})
// 顶部点单栏动画监听
this.applyAnimatedStyle('.fixtopview', () => {
'worklet'
return {opacity: `${this.topfunOp.value}`}
})
},
scrolling(e){
"worklet"
let scrollTop = e.detail.scrollTop
if(scrollTop <= 0){
//向下滚动
this.bgimgTop.value = 0
this.bgimgSca.value = 1 + (-scrollTop / 800)
this.topfunOp.value = 0
}else{
//向上滑动
this.bgimgTop.value = - scrollTop
this.bgimgSca.value = 1
let opTemp = (scrollTop / 200)
this.topfunOp.value = opTemp >= 1 ? 1 : opTemp
}
},
Tip:由于代码量较大,以下说明不会附上详细代码,待后续整理好源码,会开源的
手势系统:提升用户留存率,神之一手
这个实例呢,和第一个非常相似,是因为其中也 用到了worklet动画,换句话说,如果使用了Skyline框架,那么worklet将萦绕整个开发进展,它即代替了wss和css动画。
另外,更重要的是这个实例运用了手势系统,概而述之,就是使用<pan-gesture-handler><vertical-drag-gesture-handler>去更精细化的代理使用和监听<scroll-view>组件。
一、首页由<pan-gesture-handler>判断页面状态,状态1:往上拖动,不处理滚动事件,而是负责顶部搜索按钮和搜索框的动画效果、背景图片的缩放效果、以及整个容器的高度变化;状态2:向下滑动,则处理滚动事件
二、当判断向下滑动,处理滚动事件时,先由<vertical-drag-gesture-handler>判断<scroll-view>是否触顶,接下来也有两种状态,状态1:触顶,则改变由<vertical-drag-gesture-handler>接管,处理容器下滑的动画;状态2:没有触顶,则是<scroll-view>的正常滑动。
自定义路由 :小程序焕然一新,媲美原生
示例一:
这个详情弹出页的效果和webview下的 <page-container>组件的效果基本相似,如果这里简单的使用跳转新页面,则不符合UI设计稿,使用页面弹出组件时,又会发生用户的返回操作直接退出商品列表页,所以这里使用的自定义路由,并且还利用了worlklet和手势系统,实现了手势下滑与左滑时,如果下滑距离和下滑速度足够,则退出,不足够,则回弹恢复。
示例二:
这里的自定义路由,效果不明显,但是恰恰就需要这种效果。简单来说就是用户点击搜索框,需要跳转到搜索页面,但是设计稿中需要这种跳转是无感的,而自定义路由中将transitionDuration跳转时间设置为10或者更短,并且将handlePrimaryAnimation跳转效果设置成空值,即可完美实现。以下是简单的自定义路由配置代码:
const ShopSearchRouteBuilder = (customRouteContext) => {
console.info('skyline: half page route build')
/**
* 1. 手势拖动时采用原始值
* 2. 页面进入时采用 curve 曲线生成的值
* 3. 页面返回时采用 reverseCurve 生成的值
*/
const handlePrimaryAnimation = () => {
'worklet'
return {
}
}
return {
opaque: false,
handlePrimaryAnimation,
transitionDuration: 10,
reverseTransitionDuration: 10,
barrierDismissible:true,
canTransitionTo: false,
canTransitionFrom: false,
}
}
共享元素 :我的奇奇怪怪的使用
如果没有看出这个例子的共享元素是如何使用的,那么我用webview的页面来分解一下。
这里的商品列表页和购物车其实是两个页面,但是底部的购物车按钮元素,又需要在两个页面跳转时,无感展示,所以这里是最适合使用共享元素的,我个人认为,这比跳转页面时使详情图片在不同页面间飞跃更加高级和实用。
但是既然说到了图片飞跃的效果,下面我也来展示几个实用例子:
这里的两个例子也都是列表页跳转至详情页时,实例图片的飞跃。
当然小程序中的动画效果可不止以上罗列的这么几个,总而言之,使用了Skyline之后,以上的动画效果在小程序中随处可见,如果不是本人的代码能力有限,我想小程序的整体效果完全可以媲美APP的原生效果。
希望以上这些能够为即将进行微信小程序开发,而苦恼于是否使用Skyline的同学们,带来新的思路。
Skyline的bug:背刺与惊喜
新技术需要有勇气去使用,去克服遇到的一切问题我遇到了很多bug,虽然他总会在我意料不到的地方背刺我一刀,但是Skyline的效果实在让我欲罢不能,万分庆幸的是我真的要非常感谢微信团队的老师们,给了我很多建议与帮助。
还没有经过老师同意上图,暂时先打个码。
好了,接下来说一下,现在还没有解决的bug,希望微信团队能尽快修复。
1、小程序使用的是自定义tabbar,在ios下,相隔较长时间再重新打开小程序,会出现白屏的现象,是完全不显示任何元素,但vconsole是可以看到各生命周期已经正常允许了的。这里实在不好上传相关代码,因为首页代码很复杂。还关联了全局状态管理。
与其他同学沟通过,发现并不是我的单一案例,也有人复现了。
解决方案:万幸我使用的是自定义tabbar,小程序启动首页被我设置成了某一个单页面,然后从单页面跳转到tabbar首页,并且这个单页面还能设置成宣传海报首页,这也算是一个自洽的解决方法。
2、wx.switchTab()方法:前提依旧是自定义tabbar,假设tabbar有A、B、C、D首先进入了tabbar首页A页面,然后跳转到其他页面,如果这时使用wx.switchTab()跳转至B\C\D页面,会出现tabbar栏不出现的情况。
解决方案:全部跳转至A首页,或者tabbar页面底部安置一个假的tabbar栏。
3、最麻烦的问题:如果我不考虑兼容的问题,那么即代表我需要抛弃一部分没有升级微信版本习惯的用户,因为低版本的微信无法正常使用Skyline框架开发的小程序。
解决方案:如果您的开发成本和时间足够,完全可以慢慢兼容、如果还在纠结,建议您单页面慢慢升级Skyline,Skyline支持单页面渲染(这可真是太棒了),但是对于我这种有代码强迫症的人来说,这是硬伤,我不能忍受一个页面是webview,另一个是skyline,我只能慢慢熬过用户更新的阵痛期。
最后,我还想说几句话:
1、开源这件事,我已经做好了准备,但是开源成本太大,我还没考虑好是否花时间进行开源,总之,有需要的同学,可以写个评论支持下。
2、开发: (1)前端:有80%以上的图片与文字,都是通过后台数据渲染的,也就是说部署后,基本不需要修改小程序代码,但是自由度极高。
(2)后台框架:考虑到是小项目,只使用了java的springboot,数据库使用的是mySql,缓存则也是通过代码实现的(不使用redis,是因为云托管不支持,单独买太贵了),存储使用的腾讯的COS。
(3)后台部署:我抛弃了传统服务器,拥抱了微信云托管。
(4)管理admin页面:使用的是antd admin(vue2),部署方面同样也是使用的云托管的静态资源存储。
大佬好厉害啊,小程序要开源嘛
我跟着第一个例子敲报错了:
ReferenceError: shared is not defined
老师知道是为啥吗? 还是shared 方法的代码没贴出来?
昨天在dev分支配置了skyline,然后切换回main分支想修改代码。main分支是webview渲染,结果switchTab用不了了。。。奇怪了
我还是没搞懂云托管和云开发的区别。云开发是不是速度更快点?现在用的云服务器做的开发,快到期了想换个更有性价比的做开发
Skyline 支持单页面开启 glass-easel 吗?
之前全局开启遇到了 bug,影响到 webview 渲染模式的页面了
1. 低版本微信 wxs 事件无法执行
2. 以及所有版本微信 wxml 里的 \n 需要写成 {{'\n'}}
第一个示例的代码,直接从开发工具中复制的,显示有问题,重新附上
<!-- wxml--> <!-- 背景图--> <image src="{{pageBg}}" class=" bgimg" ></image> <!-- 菜单栏--> <view class=" fixtopview "> 这里是置顶的点单菜单栏 </view> <!-- 首先使用scroll-view的worklet:onscrollupdate事件监听页面滚动--> <scroll-view worklet:onscrollupdate="scrolling" type="list" scroll-y="{{true}}" show-scrollbar="{{false}}"> <view slot="refresher"> 这里是页面内容和 </view> </scroll-view>