让人无奈的微信小程序组件
本文相关代码地址:github
最近开发微信小程序碰到了蛮多问题,尤其是小程序里面的一些组件,实在是让人感觉即满心欢喜又无奈无语。
web-view
这个是首当其冲的组件了,业务部分场景中是使用的 H5 页面,尤其是活动页面是变化最频繁的,所以查看小程序文档,有这个组件真是让人欣喜;不过高兴太早了。
其通信机制真是让人无可奈何:
可以看到组件限制有三点:
- 自动铺满整个小程序页面
- 导航栏不可以自定义
- 两边通信需要特定的场景
小程序给 H5
发送消息容易实现,可以直接在访问链接上带上我们需要的参数消息
javascript
<web-view src="test.html?id=2"></web-view>
但是H5给小程序发送消息则需要在特定的场景:后退、销毁、分享三个场景页面才能与小程序通信。意思就是没有发生上面三个场景的情况下,小程序是无法通过 bindmessage
这个事件获取到页面消息。
我们大部分场景下是需要实时通信,这里使用后退这个场景来实现实时通信,但是这个其实是牺牲了用户体验:
中间页面 middle
利用中间页面 onLoad
中接收参数 options
,再根据 getCurrentPages
获取到需要返回到页面,设置需要的消息
javascript
onLoad(options) {
const pages = getCurrentPages();
console.log(`middle消息:`, options)
const webviewPage = pages[pages.length - 2];
webviewPage.setData(
{
options: options
},
() => {
wx.navigateBack({
delta: 0,
});
}
);
}
目标页面获取消息
由于通过 middle
页面设置了 data
数据 options
所以可以在程序内访问到实时的通信消息
javascript
onShow() {
this.setData({
src: 'https://imondo.cn/files/web.html'
}, () => {
console.log(`web页:`, this.data.options)
if (this.data.options) {
wx.showModal({
title: this.data.options.msg
});
}
})
}
我们可以看到实际效果:
scroll-view
这个滚动区域组件,应该是我们真常用的组件,但是它竖向滚动的时候,一定要给它设一个固定高度值,这也是一个奇葩的设定。
幸好小程序有 wx.createSelectorQuery 这个 API 来动态解决它的高度:
javascript
// view
<view>
<view class="head">Head</view>
<scroll-view scroll-y="true" style="height: {{scollHeight}}px">
<block wx:for="{{20}}" wx:key="index">
<view class="scroll-item">item</view>
</block>
</scroll-view>
</view>
// js
onShow() {
const system = wx.getSystemInfoSync(); // 系统高度
const height = system.windowHeight;
this.queryEl(['.head']).then(rect => {
const [{ height: ht }] = rect
this.setData({
scollHeight: (height - ht).toFixed(0)
})
})
},
queryEl(selector) {
return new Promise(resolve => {
const query = wx.createSelectorQuery(); // 如果是在 component 内需要使用 .in(this)
if (Array.isArray(selector)) {
selector.forEach(el => {
query.select(el).boundingClientRect();
})
} else {
query.select(selector).boundingClientRect();
}
query.exec(res => {
resolve(res);
})
})
}
总结
小程序的组件使用过程中其实文档中都提到了相关的注意地方,但是我们的业务需求实在是多变,对于部分组件的不确定性需要好好的调研总结,希望小程序组件越来越完善吧~ 🤣