之前试水的项目下水了~开发过程中又踩了不少坑,绝大部分为微信自己的坑,在此记录希望大家看到能高效解决或避免。
1. 理解原生组件和原生组件的限制
小程序原生组件的使用限制
原生组件和非原生组件的区别
可以说开发过程中遇到的大部分奇奇怪怪的问题都是因为没有注意到原生组件使用限制导致的,其中input是最怪异的,它只在focus时是原生组件,blur状态是非原生组件,所以在你聚焦失焦的过程中有个渲染切换的过程,在我这带来了以下几个问题。
(1. 模态框弹出情况下停留在页面, 息屏再打开,账号输入框覆盖在模态框上面。
原因:进入页面时账号输入框自动获焦,focus时的input组件为原生组件,层级最高
解决方法:在willMount而不是DidShow生命周期中调用账号输入框获焦,这样在息屏后亮起是不会触发的
(2. 输入账号后 placeholder没有消失
原因:参考官方说法
因为是聚集时的input是用原生渲染,有个web渲染跟原生渲染的切换过程,所以会有个重叠
,看社区18年9月份就在众测优化了但是似乎还是没有解决解决方法: 自己实现placeholder,即判断输入框里没有值时显示placeholder
(3. 弹出模态框后,模态框中input无法自动获焦
原因:官方tip在 input 聚焦期间,避免使用 css 动画
, 模态框弹出有一段css动画
解决方法: input 聚焦给个延时,动画结束后再设置
2. 虚拟输入框fake-input, 设置透明度为0 还是能看到输入的内容及光标
原因:兼容性问题,社区有人提了iphoneX 小程序input无法隐藏,我自己就是x但是没做真机测试没发现,开发工具上没问题
解决方法:使用定位将input移出屏幕外面。增加input的padding,使之依旧能覆盖到6个小的input框
3. 地图相关
首先小程序的地图的展示是限制了只能用腾讯地图的,但是高德地图也提供了快速生成图片的替代方法,如果可以满足的需求的话也可以考虑一下,api相关没有太大的差别,腾讯地图有每日最高限额和并发限额,国内的可以免费申请提额,高德似乎没有,但是海外位置服务应该是都需要购买的,否则都有限额
(1. translateMarker 的参数animationEnd 在安卓不能正确触发
(2. 更新了marker起点的情况下,同一个marker id不能连续移动两次
以上已经在社区提出issue
第一个问题暂无回复,第二个问题果然 官方回复,marker位置为了优化性能有做缓存,这边还是自己更新markerId解决
4. 渲染层错误 Expect END descriptor with depth 0 but get another
这个问题到现在都还不明确是哪边的问题
但是因为taro编译过代码,我在开发工具里看dist文件夹中编译完的代码 并没有找到类似上述使用情况的,最后的解决方法还是很白痴的取消了自定义组件的嵌套,一大堆代码放在一个文件里解决的。。就真的很白痴。。。
5. 全局变量在拦截器中未正确更新
//设置全局变量 this.baseURL
constructor (props) {
super(props);
this.state = {};
this.baseURL = "";
}
//拦截器
envInterceptor = (chain) => {
const requestParams = chain.requestParams;
if(requestParams.url.indexOf('http') === -1)
requestParams.url = `${this.baseURL}${requestParams.url}`;
return chain.proceed(requestParams).then(res => console.log("envInterceptor", this.baseURL))
};
//在willMount获取页面参数赋值给全局变量并设置拦截器
componentWillMount() {
console.log('index willmount');
const { baseURL, applicationOID } = this.$router.params;
console.log("index willmount", baseURL);
this.baseURL = baseURL || Taro.getStorageSync('baseURL');
baseURL && Taro.setStorageSync('baseURL', baseURL);
Taro.addInterceptor(this.envInterceptor);
console.log("SDKVersion", Taro.getSystemInfoSync().SDKVersion);
console.log(Taro.getSystemInfoSync().brand + " " + Taro.getSystemInfoSync().model);
}
官方回复,拦截器内是用闭包函数实现的,销毁页面对象并不会销毁该全局对象,将在下个版本修复,因为对用户没影响只对测试有影响,所以我也不打算先对这个问题做修复了。
6. getStorageSync不是每次都能成功的
官方回复 getStorageSync不是每次都能成功的,如果存放了重要数据建议加个try catch或者用异步方法在success里做后续操作