mpvue开发探坑实录

首先说明一下为啥使用mpvue。这次项目是商城开发,要求同时上线小程序与微信公众号。为了后期的维护与迭代方便,计划一套代码多平台共用。对于无法共用的代码使用webpack在打包时进行区分(具体实施方法是组长完成的)。 在此记录一下开发过程中遇到的坑(大多都是mpvue/小程序遇到的坑),与诸君共勉。

1.mpvue大数组更新

①具体任务

在菜品列表里,需要对全部菜品(大概20到1000不等)的菜品进行列表展示,并提供加减菜操作。为了显示优化要有懒加载(滚动到哪里,加载当前显示列的菜品)。

②具体问题

其实思路很简单,将数组用v-for进行遍历,然后根据滚动事件返回的距离动态修改数组内的值。在web中使用很流畅没有其他问题,但是在小程序中,20道菜以下使用尚可,20到80道菜有卡顿,80到120道菜卡顿严重,在230道菜的时候小程序会大概率直接卡死退出。 我当时自测用的手机是小米mix2s,按理讲满血骁龙845都带不起这个小程序,也不要期待中低端机型能流畅使用了。

③分析

卡顿包括卡死是发生在菜品列表组件,也就是scroll-view滚动时发生的,要搞清楚在这一次滚动中发生了什么事情。 首先是触发滚动,然后根据滚动事件的高度算出在新区域内需要渲染的新的菜品信息(替代之前的空白内容或者说是占位内容)。再然后是将新的菜品信息更新到长数组中,最终页面渲染结束,用户就在一次滚动后看到了新的菜品列表信息。 那么问题基本就是出在滚动触发,新菜品计算,数据更新以及页面渲染这四个方面中。

④解决方案

滚动触发:

小程序的scroll-view好像对于滚动事件本身有做过节流。我需要让滚动只在最后一次触发,所以对滚动事件进行防抖处理。

let first = true;
debounce(firstfn, endfn, interval) {
	if (first) firstfn();
	first = false;
	if (timer) clearTimeout(timer);
	timer = setTimeout(function () {
		endfn();
		first = true;
	}, interval);
}
复制代码

因为种种原因(后面会说)引不了vue的节流与防抖,纯手写的,可能不太好但是能用。这样滚动事件只会在滚动的第一次和最后一次触发,从而减少滚动的请求次数。

数据更新

mpvue中对于长数组的处理可能和我们理解的不太一样。在mpvue中如果对数组内某一值进行修改,并不是对当前值进行this.setData,而是整个数组重新this.setData。也就是说对于数组的任何变化都会引起整个数组在页面中的重新渲染。 最后的解决方案是——放弃mpvue。 ... 当然不是全盘放弃,菜品列表这一块(主要是将占位信息改为真实菜品信息的功能)改用小程序语言编写,做成小程序组件重新引入到mpvue的代码中。

// productList为用于展示的长数组
// realList为全部真实菜品数据
let data = {}
data["productList[" + num + "]"] = Object.assign(data,realList[num])
this.setData(data)
复制代码

通过这种方法在小程序中就可以只对数组内的某一值进行修改而不会需要重新赋值整个数组。

循环内容中包含组件

将循环内的加减号组件也改写成小程序组件。

总结

总之,减少组件嵌套,大数组值处理改用小程序语言编写。

ps:在mpvue新版(1.0.18)中官方对于大数组赋值好像有优化

2.输入框输入文本抖动

先说一句,mpvue新版(1.0.18)中已经对此问题进行了解决与优化,虽然在focus时还是有些抖动但是已经好了相当多。因此我的解决方法还是针对之前的版本。

其实引起文本抖动的主要原因是使用了v-model。 最好的方法是放弃v-model,改用:value和@input代替v-model。

<input :value="iptValue" @input="input" />
复制代码

如果坚持要用v-model(比如项目需要兼容公众号和小程序),可以用lazy修饰符解决问题。虽然在blur后会闪一下,但是在输入的时候问题不会很大。

<input v-model.lazy="iptValue" />
复制代码

3.mpvue性能优化

说回上文,虽然滚动流畅了,但是加减菜的操作却有比较大的延迟——点击"+"后大概半秒到三秒后菜才加入购物车并且数量发生变化——这个就很难受了。 苦苦找不到原因后还是组长发现了问题(大佬流啤啊...) 在mpvue中值发生变化的时候,页面内所有的值都会更新一次,这个值包括页面内所有组件的data,props,computed中的非对象的值。测试时在改变一个值后,触发了14次的所有值更新。 所以优化方案就是减少data,props,computed的使用。

computed

能放弃使用就放弃吧,小程序中原本就没有computed和watch。如果需要可以少量使用。

props

对于不需要经常变化的props就合并到一个对象中传入组件,mpvue对于对象有单独的优化,不会进入到更新的。

data

data中只放入需要在页面中渲染或者向其他组件传递的值,不需要渲染的值全部放在data外

...
let num = 0; // 不需要渲染
export default {
	data(){
		return {
			show:true // 需要渲染
...
复制代码

watch

watch这个对于我来说有点玄学,我发现使用watch后组件间传值在ios真机时会变得比较慢(400ms到2300ms左右)。所以能不用就不用吧,尤其是watch的深度监听。如果要用深度监听,就改用另外的比较简单的值(比如Boolean)监听。

4.小程序的上拉加载和下拉刷新

两种方案,第一种是使用小程序提供的onPullDownRefresh与onReachBottom,不过这两种属于页面事件,如果需要区域内下拉刷新和上拉加载并不适用。第二种是手写上拉加载和下拉刷新,没有API我们就自己造轮子。不过自己造多半都是用css3动画,css3动画在小程序中并不流畅,所以... 归根结底还是要和产品定好了,一定要说服ta

5.小程序与公众号的代码区别(部分)

因为当前项目是公众号和小程序共用一套代码,但是有些效果或者api还是有差距的,列一下遇到的比较大差距的情况。

获取用户信息方式

小程序可以通过open-data组件以及wx.getUserInfo获取用户的信息(包括头像,昵称,性别等) 公众号现在已经无法通过jssdk获取用户信息了,只能靠后台传递获取的到微信用户信息

mounted,onShow

其实还是说的是小程序和web的区别,web在前进后之前的页面会被销毁,而小程序前进后之前页面会被“冻结”。所以退回进入上一页面时web会触发mounted,而小程序触发的是onShow(小程序生命周期函数)。 在web中写小程序的生命周期函数并不会报错,也不会触发。 关于后退时当前页面的问题下一问题再说。

6.mpvue页面数据缓存问题

在由mpvue编译的小程序从A页面进入B页面,再从B页面回到A页面,然后再从A页面进入B页面后,上次的数据依旧保留。说的比较复杂,其实就是从列表页先后进入不同的详情页,第二次的详情页还会带着上一次的数据。 在我看来数据缓存是把双刃剑——对于每次进入页面都需要执行的方法现在只需要执行第一次就好了(比如一些算高算距离用于展示的值)。但是每次进入都要再次请求的数据(比如详情信息),重新进入页面都会带着上一次的数据可就不太好看了。 主要原因是在小程序后退时页面会被销毁(onUnload),但是存于mpvue中的值依旧还存在并没有被销毁。所以在onUnload时清除一次mpvue内的data数据即可。

onUnload(){
	Object.assign(this.$data, this.$options.data());
}
复制代码

7.小程序的吸顶效果

吸顶效果我能想到的实现方式就两种。

页面滚动检测

用onPageScroll检测页面滚动的高度,达到指定高度为元素增加position:fixed属性。这种方式是能实现,但是有比较大的延迟(类似于麦当劳点餐侧边栏那种)

sticky

使用css的粘性定位实现吸顶,这种方式没有延迟效果好。但是最大的问题就是....兼容性不好,小程序基础库在2.3.2版本的时候基本不支持sticky,升级到2.4.2的时候部分支持sticky。 我自己测试的结果是IOS基本都支持(只测试了iphone5,iphone6在ios12下),安卓平台并不确定。 我本着能用就行,不用也不影响操作的心态使用的粘性定位,也不知道哪几款机型不支持....

8.IOS问题

IOS啊,我大部分不能解决的问题基本都是因为IOS系统,大概列一下吧... 就遇到一次,另外一个同款同型号同系统的手机都没事,之后让组件延迟创建就没问题了。

IOS10上vant(有赞)的popup偏移

我看官方文档上最新版的已经解决了IOS8的popup偏移问题,但是我这边测试的IOS10下依然也有偏移问题。

IOS小程序页面有上拉下拉动画

测试结果: enablePullDownRefresh:false 无效 disableScroll:true 有效,但是本身就是列表页,不可能禁用滚动。 目前没找到更好的方法...

IOS真机小程序组件传值过慢

这是之前第一个问题中遇到的。我从mpvue写的vue组件向我用小程序语言写的小程序组件传值(长数组),在IOS真机下大概花费了1400ms到2300ms,这个时间也太长了。之后我精简了数组内容,并且先传短数组后传长数组提升用户体验,这个优化后的传值也大概花费了1000ms到1500ms。 目前没有彻底解决...

9.总结

头一次写mpvue项目,也是头一次接触小程序项目。埋坑跳坑中在不到一个月内的时间把项目基本流程完成了,自己能力还是不足啊。 “埋坑”仍未成功,代码...还需优化啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值