微信小程序
独有特性
分享卡片进入会创建新页面栈
小程序已启动且切换到后台的情况下,再通过分享卡片进入,会新创建新的页面栈,之前的页面栈会销毁。目前没有相关文档记载,但实际情况就是如此。
WXS
WXS 运行于视图层,与 WXML 是在同一个线程运行,避免了跨线程与逻辑层通信的开销。详见:如何评价微信新推出的WXS语言? - 鲁小夫的回答 - 知乎open in new window
生命周期
父子组件生命周期顺序
假设首页页面里引用组件 Parent,组件 Parent 里引用组件 Child,组件 Parent 和 Child 里都有pageLifetimes.show/hide
生命周期。
首次打开小程序并进入页面时,各生命周期的调用顺序为:
- App.onLaunch
- App.onShow
- ComponentChild.created
- ComponentParent.created
- ComponentParent.attached
- ComponentChild.attached
- Page.onLoad
- ComponentParent.pageLifetimes.show
- ComponentChild.pageLifetimes.show
- Page.onShow
- ComponentChild.ready
- ComponentParent.ready
- Page.onReady
切到后台时,各生命周期的调用顺序为:
- ComponentParent.pageLifetimes.hide
- ComponentChild.pageLifetimes.hide
- Page.onHide
- App.onHide
切回前台时,各生命周期的调用顺序为:
- App.onShow
- ComponentParent.pageLifetimes.show
- ComponentChild.pageLifetimes.show
- Page.onShow
页面销毁时,各生命周期的调用顺序为:
- Page.onUnload
- ComponentChild.detached
- ComponentParent.detached
测试所用代码片段:https://developers.weixin.qq.com/s/HeI1uAm87kjEopen in new window
其他:
- 组件加载后注册了
pageLifetimes.show
之后,会在后续的页面onShow
时触发
疑难杂症
如何隐藏 scroll-view 滚动条
以scroll-view
为横向滚动为例,该方式是给scroll-view
增加一个父元素,父元素的高度固定,并设置overflow: hidden
;scroll-view
作为子元素,其高度超过父元素高度,以便将滚动条置于父元素高度之外。注意,若是直接给scroll-view
增加padding-bottom
不能将滚动条置于最底部,可尝试给scroll-view
的子元素添加padding-bottom
。
此外,可尝试设置scroll-view
的show-scrollbar
属性为false
,以隐藏滚动条。
<scroll-view :enhanced="true" :show-scrollbar="false"></scroll-view>
注意,需要开启enhanced
属性之后,设置show-scrollbar
方才有效。
禁止页面顶部下拉或底部上滑的弹性效果
若是页面只有一屏,可设置页面配置里的disableScroll: true
。
若是页面内容较多,需要竖向滚动,可以使用scroll-view
包裹所有内容,并设置:
<scroll-view :scroll-y="true" :enhanced="true" :bounces="false">
<view><view/>
...
</scroll-view>
2
3
4
注意,需要开启enhanced
属性之后,设置bounces
方才有效。
1rpx 圆角边框缺失或不清晰
若使用 1rpx 的边框但不设置圆角,正常情况下都会显示正常;但若是设置了圆角,会出现边框缺失或者不清晰的问题。
解决方案:按 2rpx 或 3rpx 的边宽实现,再 scale 为原来的 1/2 或 1/3,详见retina-borderopen in new window
子组件上添加样式
若是想在子组件上添加样式,比如background-color
、margin
等,请先将子组件的display
置为非inline
即可。但是理论上来说,即使是display: inline
,background-color
也是能生效的,没明白是怎么回事。
<template>
<div>
<child-component class="child-component"></child-componet>
</div>
</template>
<style lang="less" scoped>
.child-component {
display: block; // 只要不是 inline 即可
margin-top: 12rpx;
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
包含自定义组件的元素的 opacity 的 transition 无效
<view class="ctn">
<child-component></child-component>
</view>
2
3
.ctn {
position: absolute;
transition: opacity .5;
opacity: 0;
/* 解决 opacity 不生效的问题 */
z-index: 1;
}
.ctn.visible {
opacity: 1;
}
2
3
4
5
6
7
8
9
10
当元素是position: absolute/fixed
时,且包含了自定义组件,若不设置z-index
为大于0
的数值,则opacity
的transition
对自定义组件不会生效。
开发
反编译
小程序上传打包产物
miniprogram-api-typings
安装并配置miniprogram-api-typingsopen in new window。配置好之后,miniprogram-api-typings
里的绝大部分的声明都在WechatMiniprogram
这个命名空间之下,且WechatMiniprogram
是个全局的命名空间对象。如下以微信卡券相关方法为例,简单介绍使用方法。
假设项目里将wx.addCard
封装成 Promise 调用。
// 方式一:直接获取命令空间下的声明 WechatMiniprogram.xxx
const addCard = (card: WechatMiniprogram.AddCardRequestInfo): Promise<WechatMiniprogram.AddCardResponseInfo> => {
return new Promise((resolve, reject) => {
wx.addCard({
cardList: [card],
success(res) {
resolve(res.cardList[0]);
},
fail() {
reject();
},
});
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
// 方式二:采用命名空间的别名(推荐)
import AddCardRequestInfo = WechatMiniprogram.AddCardRequestInfo;
const addCard = (card: AddCardRequestInfo): Promise<AddCardResponseInfo> => {
return new Promise((resolve, reject) => {
wx.addCard({
cardList: [card],
success(res) {
resolve(res.cardList[0]);
},
fail() {
reject();
},
});
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
miniprogram-api-promise
miniprogram-api-promiseopen in new window,扩展微信小程序的 API,以支持 Promise 形式调用。