背景
9月和10月,穿插开发了两个项目,其中一个是对原有微信小程序进行重构。起初产品那边只是希望界面改版外加增加一些新功能,而我看了之前的项目代码后,强烈建议重构,很欣慰领导们最终也同意了我的提议。
之前的微信小程序使用的是原生语法开发,目录结构和代码都较为混乱,几乎没什么组件复用,一个页面文件或者js文件动辄上千行,实在是没什么心情维护。于是便采用mpvue+typescript进行重构,自觉重构之后代码清爽了很多。
当然,由于是第一次独自开发正式的小程序项目,在开发过程中也遇到了一些问题,在此记录一下,希望能帮助遇到同样问题的小伙伴们。
问题及解决
-
swiper样式修改
首页需要开发一个轮播图,于是使用了小程序的原生组件swiper,不得不说还是很方便的。具体配置可参见官方文档。但是轮播图中的样式就需要修改了,由于vue文件的样式增加了scoped属性,所以在写less的时候需要增加
/deep/
才能使样式生效,具体代码如下:.homepage_main_banner_swiper { height: 100%; width: 100%; position: relative; /deep/ .wx-swiper-dot { height: 12rpx; width: 12rpx; background: rgba(23, 109, 244, 0.8); } /deep/ .wx-swiper-dot-active { width: 32rpx; height: 12rpx; border-radius: 6rpx; background: rgba(23, 109, 244, 1); } }
-
picker在安卓上是循环的
在做选择框时,使用了picker组件,而在测试过程中,发现在安卓真机上当picker内的数据多时,选择列表会触发循环,在查阅了相关资料后发现这似乎是原生组件自带的一个bug,而到目前为止也暂未得到解决。
-
input动态改变type在安卓上有bug
在做密码输入框时有一个密码的显示隐藏功能,这时我想要动态改变input的type属性来实现:
<input :type="showPwd ? 'text' : 'password'" />
在开发者工具上并未发现有何不妥,但是在测试阶段发现,在安卓设备上并不能动态切换input的类型,迫不得已最终只能写了两个不同类型的input,通过
v-if
来控制显隐。 -
显示html代码段及rich-text图片缩放
在mpvue的文档上,显示mpvue并不能像vue一样可以直接使用
v-html
来显示html代码片段的,然而在实际开发过程中发现,是可以直接使用v-html
的,可能是新的mpvue版本已经增加了这个功能而文档并未更新。而
v-html
中的内容编译成小程序之后是rich-text
,当其中包含图片时,发现并不能直接通过css选择器选择到rich-text
中的元素,就只能使用正则替换原html字符串中的内容了。如我需要使
rich-text
中的图片进行自适应,就需要给img
设置宽高:html.replace(/<img[^>]*>/gi, function (match: any) { return match.replace(/style\s*?=\s*?([‘"])[\s\S]*?\1/ig, 'style="max-width:100%;height:auto;"')})
-
live-player全屏
小程序的
live-player
组件本身并不像video
那样可以设置播放控件,而我需要提供全屏按钮,这时就需要自己额外写一个了。<live-player :src="liveSrc" mode="RTC" autoplay @fullscreenchange="onFullscreenChanges" @statechange="liveStateChange" @error="liveError" style="width: 100%; height: 100%;" > <cover-view class="full_button" @click="handlefullScreen"> <cover-view v-if="!fullScreenFlag"> <cover-image :src="AppImages.ICON_INTOSCREEN" class="full_img" /> </cover-view> <cover-view v-else> <cover-image :src="AppImages.ICON_OUTSCREEN" class="full_img" /> </cover-view> </cover-view> </live-player>
public handlefullScreen() { if (!this.fullScreenFlag) { this.livePlayer.requestFullScreen({ direction: 90, success: (res: any) => { this.fullScreenFlag = !this.fullScreenFlag }, fail: (res: any) => {} }) } else { this.livePlayer.exitFullScreen({ direction: 0, success: (res: any) => { this.fullScreenFlag = !this.fullScreenFlag }, fail: (res: any) => {} }) } }
-
跳转菜单页面不支持redict不能传参
对于小程序内的页面跳转传递参数,普通页面可以使用
wx.navigateTo({ url })
,其中url后面使用?
携带参数,例如我需要跳转到视频详情页面:const url = `${AppUrls.SUBJECT_DETAIL}?courseId=${this.courseId}&lessonId=${this.lessonId}&type=${type}&name=${this.courseName}` wx.navigateTo({ url })
在详情页面中可以通过
this.$root.$mp.query
获取到这些参数。而当我需要跳转的菜单是底部菜单页面时,也就是在
app.json
中配置的tabBar
页面时,需要使用wx.switchTab({ url })
进行跳转,而此时是不支持传递参数的,这就使得我们需要定义一个全局变量或者使用数据仓库来传递参数,而我在项目中是使用store
进行参数传递的。 -
访问web页面
小程序中如果想要跳转到外部的web页面,需要使用到web-view组件,注意文档中的说明,目前个人类型的小程序是不支持使用的,也就是说,如果希望跳转到外部页面,必须要求是企业版的小程序。
具体使用方式的话很简单,查看使用文档即可。
-
滚动到底部加载更多
滚动到底部触发
onReachBottom
方法即可,唯一需要注意的是不能给最外层的盒子设置固定高度,否则会无法触发onReachBottom
方法。 -
获取当前页面路径
private getCurrentPageUrl() { const pages = getCurrentPages() const currentPage = pages[pages.length - 1] return currentPage.route }
-
mpvue不会销毁组件数据
使用mpvue开发时发现mpvue并不像vue一样会自动销毁组件,很可能也是与小程序的机制有关,所以为了避免上一次数据的影响,我们需要在离开页面时手动清空数据。
我是选择在小程序的
onUnload
生命周期内实现这一操作,例如:protected onUnload() { Object.assign(this, { pageLoading: false, liveList: [], pageNow: 1, recordCount: 0 }) }
-
设置png背景图
小程序在设置背景图时需要使用网络图片,如果是比较小的图片我会直接放在本地资源中,使用
img
的形式引入,而如果是比较大的资源,则会上传到微博上,引用其网络链接。但是用微博当图床有两个缺点:一个是微博会压缩用户上传的图片,造成清晰度下降;二是微博并不支持
png
格式的图片,会自动转换成jpg
。而本次开发中恰好需要上传几张png
格式的背景图,在一番搜索之后,我发现了路过图床,免费好用,完全满足需求。 -
分包加载
由于小程序单个包大小不能大于2M,所以当项目体积较大时,需要使用分包加载,在
app.json
中配置:"subPackages": [{ "root": "packageA", "pages": [ "pages/index/main" ] }]
更多配置详见:官方文档-分包加载
-
catchtouchmove
在项目中做了一个弹出框,而在测试过程中发现,小程序可以透过弹出层滑动弹出层以下的页面,这时如果是原生写法可以设置:
<view catchtouchmove='handleTouchMove'></view>
只需要写一个空函数即可,而在mpvue中,这种写法并不管用。经过一番搜索,我发现正确的写法应该是以下这样:
<div @touchmove.stop="preventTouchMove"></div>
-
键盘弹出与输入框的距离、能看到上一个页面的内容
在小程序中进行输入框输入的时候,发现了有的地方弹出的输入法挡住了输入框,而有的地方输入法弹出来之后,在输入法与输入框直接的间隙可以看到上一个页面的内容,无论是哪一种情况,用户体验都不好。
在查看了小程序开发文档-input之后,发现需要设置
input
的cursor-spacing
属性。而具体的值可能需要根据页面内容多实验几次找到一个最佳值。 -
分享转发
如果只是希望页面可以被转发,则直接添加
onShareAppMessage
方法即可;如果是希望自己实现一个转发按钮,则需要先设置<button open-type="share">
,然后添加onShareAppMessage
方法。onShareAppMessage(res) { return { title: '转发标题', path: '页面路径', success: res => {} } }
更多配置参加官方文档-onShareAppMessage
-
ios设备白屏
小程序测试过程中发现在9.x版本的ios系统上会出现白屏的问题,搜索了很久,发现虽然也有很多人遇到了类似的问题,却都并没有找到解决方案。
而在我一次提交代码时,勾选了开发者工具中的“ES6转ES5”选项之后,发现白屏的问题得到了解决。猜想可能是老的系统不支持ES6的语法。
-
ios设备滚动不流畅
小程序测试过程中发现在ios设备上并不能像安卓设备一样丝滑般的滚动,总是有一种卡顿的感觉。经过一番搜索发现,需要给滚动的元素添加以下样式:
div { -webkit-overflow-scrolling: touch; }
-
ios客户端不允许涉及虚拟商品的购买及支付功能
经过一个多月的开发,小程序终于提交审核准备上线了,而提交过程又是一波三折。
由于我们的小程序设置到虚拟商品的支付,而这在ios上是不允许的,所以导致了审核不通过。而对于这一问题的解决方案,经过一番调研发现基本只有以下3点:
- 后台设置开关过审,审核的时候关闭各项虚拟商品支付功能,待审核通过后打开。无疑这样做是有风险的,是不合规定的,而一旦被发现,也会被官方惩罚。具体惩罚措施暂不清楚。
- 放弃ios端支付,针对ios和安卓设计两套不同的界面,安卓可以进行虚拟商品的购买,而ios端不展示价格也不提供购买功能。这样做的话无疑是舍弃了ios端的资源,会少很多money。
- 将虚拟商品转变为实物商品,或者是买实物商品赠送虚拟商品,但这会增加邮寄费用,且对页面的改动也会较大。
最后经过领导们的决议,确定了第二种方案,小程序也终于得以上线。
End
最后,欢迎大家来访问我们的小程序,也欢迎大家提出宝贵的意见和建议~~