手机版

mpvue开发音频小程序踩坑建议详解

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

这是我第一次开发小程序,我开发的产品都是音频产品。在老大哥的建议下,我采用了mpvue,一个星期就做好了所有功能。因为不熟悉mpvue和微信小程序,花了一周时间改bug,才出了一个好用的版本。在这里,我将整理和分享我在开发过程中遇到的一些问题,并给出一些建议。

在Linux上开发小程序

公司电脑安装双系统,日常使用Ubuntu系统,Linux或Mac的开发环境对前端相对友好。微信小程序的官方开发者工具只有Windows和Mac版本,这就比较尴尬了。

幸运的是,我发现一些大神已经在GitHub上支持了Linux,并推荐给大家:Linux微信web Developer Tool。它可以根据教程进行安装和使用,也可以使用。/bin/wxdt命令。但是用了几天,觉得不方便,就干脆切换回最新的正式版Windows系统。

将wx.request打包为Promise

Wx.request用于发起http请求,但通常用于编写Promise,所以最好将这个方法封装成Promise的形式。我看到很多小程序都会用到fly库。

不过我个人觉得没有必要推出功能这么强大的请求,小程序本身应该是轻量级的东西。引入一个库可能会导致更大的项目包,并可能使小程序更难实现。所以,抱着能自己写的心态,自己包装就好。

在src/utils中,创建一个新的request.js:

const apiUrl=' https://your您的server.com/api/'const请求=(apiName,reqData,issholoading=true)={//如果(is show loading){ wx . show loading({ title : '尝试加载,mask: true }) }返回新的Promise(函数(解析,拒绝){ wx . request({ URL : APiURl APiNAmE,method: 'POST ',data: reqData,Header:) 当然,这是一个简化的版本,在我的实际项目中,一些参数(如token)将在初始化过程中添加,因此您可以看到它被打包为Promise。

使用万维

小程序已经支持npm安装,但是不太擅长。或者按照线上的方法,克隆项目放在静态目录下。

git clone https://github.com/youzan/vant-weapp.git然后将vant-weapp的dist目录复制到项目的静态目录(尽可能简洁,删除一些奇怪的东西,比如。github,所以直接使用dist目录),并将其重命名为vant(或not)。在全球范围内使用时,您可以介绍:

使用组件' : { ' van-button ' : '/static/vant/button/index ',' van-field ' : '/static/vant/field/index ' },注意:微信开发者工具中ES6转换成ES5的功能需要开启

一开始以为和网上的没什么区别,没想到这么麻烦。比如v-model可以用在vue中,但是不能用在mpvue的小程序中,只能用

van-field : value=' password ' type=' password ' @ change=' pwd change ' input-class=' my class '/并且不能灵活添加类来修改组件的样式,只有vant组件支持提供外部样式时才能修改。比如上面的van-field是通过input-class添加样式来控制的,非常不方便。而且有些内部样式是不能更改的,因为没有外部样式表。

综上所述,微信小程序中使用第三方组件库不方便,修改样式比较麻烦。如果产品有UI设计,尽量不要用。有时候自己实现风格可能更快,项目量也更小。

使用vuex

在mpvue的官方快速模板中,vuex被放置在counter的页面目录中。很多习惯了vue官方写法的同学(包括我)都不太喜欢,最好改成vuex官方写法。

在src目录下创建一个store文件夹,并分别创建以下文件:

当项目不太复杂,使用起来比较麻烦时,不建议使用模块。

粘贴index.js的代码,其他actions.js和getters.js会以官方方式编写。

从“vue”导入Vue从“Vuex”导入Vuex *作为操作从。/actions“import *作为getters from”。/getter“从导入状态”。/state“从导入突变”。/ventures ' import create logger from ' Vuex/dist/logger ' vue . use(Vuex)const debug=process . ENV . NODE _ ENV!=='production '导出默认新Vuex。Store({ actions,getters,state,突变,strict: debug,plugins: debug?[create logger()]:[]})vuex/dist/logger是VUEX可以在开发环境中自动打印日志的工具。调试方便,推荐。然后在src/main.js中介绍:

从“vue”导入Vue从“App”导入。/App ' import Store from ' @/Store ' vue . config . production tip=false App . MP type=' App ' vue . prototype . $ Store=Store const App=new vue({ Store })App。$ mount(),以便它可以在项目中正常使用。完全支持mapState、mapActions、mapGetters的写入,例如在page/index/index . vue中:

scriptimport { mapState,mapActions }从' vuex '导出默认{ computed: {.mapState(['myAudio']) },Methods :map actions (['my actions'])},created () {this。my actions()//调用vuex } }/脚本中的方法踩坑指南

其实大部分的坑可能都是mpvue的,很多时候他们都不熟悉一些小程序生命周期造成的奇怪bug。

Mpvue支持小程序的本地组件

Mpvue在applet中将div编译成视图。刚开始没看懂,以为用了mpvue之后就不能用小程序原来支持的组件了,比如swiper、scroll-view等。小程序是支持的,所以我可以放心使用。

npm运行构建后失去风格

本来开发环境是正常的,准备发布npm run build之后,发现风格丢失了。然后,再次使用npm start对问题进行故障排除,仍然缺少样式。此时,我的心是mmp的:忘记npm跑搭的损失。为什么在我什么都没改变重新启动npm start后它还是丢失了?以前很正常吗?

一开始我怀疑是缓存问题。我尝试删除dist目录,重启开发者工具,甚至重启电脑。这是我遇到的超级诡异的问题之一。

静下心来想:以前的版本很正常,一定是新版本引入了什么东西导致包装风格的丢失。然后,回滚版本一个一个地构建,最后找出原因:将其他页面引入一个页面,也就是将另一个页面导入页面。

我这里的具体例子是:我想在pages/index/index.vue中共享一个底部的tabbar,页面根据tabbar的值显示对应的子页面: pages/page1/index.vue和pages/page2/index.vue。

所以我把这两个页面作为子组件引入:从' @/pages/page1 '导入Page1,刚开始没有问题。重新启动项目或构建后,我发现样式丢失了。

这可能是mpvue打包机制的一个限制,即一个页面不能引用另一个页面作为子组件,否则样式会丢失。

无法读取背景音频的Src

在项目中,用户在退出小程序后想要播放音频,所以使用了后台音频的API:wx . getbackgroundaudio manager()。

this . audio=wx . getbackground audio manager(). this . audio . src=' http://ws . stream . QQ music . QQ.com/m 500001 vfvsj 21 xfqb . MP3?guid=fffffffff 82 de F4 af 4b 12 B3 CD 9337 D5 e 7uin=346897220v key=6292 f 51 e 384 e 061 ff 02 c 31 f 716658 E5 c 81 f 5594d 561 f2e 88 b 854 e 81 caab 7806 d5e 4 f 103 e 55d 33 c 16 F3 fac 506d 1 ab 17 2d e 8600 b 37 e 43 fad frotag=0Max_age=2592000 '标题和src赋值后会直接播放音频,建议填写以下属性,因为微信有一个界面,播放背景音频时需要封面图片和歌手名字。

如果你想获得当前播放的音频src,你认为你可以通过这个. audio.src来获得,但是有一个错误。

可以在开发者工具中正常获取,也就是开发的时候还可以,但是在真机上返回的时候是未定义的,所以不能用this.audio.src来获取当前播放的音频url,必须用一个变量来存储这个数据。

直接使用音频的当前时间可能无法及时呈现

CurrentTime用来显示当前的播放进度,但是我在子组件中使用的时候,经常没有及时更新,打印正常,但是尝试渲染不及时,有时候需要点击重新渲染,使用mpvue的时候可能会遇到这种情况。

因此,建议项目本身维护一组背景音频变量,比如在vuex中。听一下backgroundAuditManager。OnTimeUpdate()方法,并将其分配给每次自己维护的变量。

音频的onCanplay方法不一定会触发每个音频

一开始听了onCanplay的方法,把音频的时长信息分配给vuex存储,但是发现onCanplay有时候是不会触发的,比如重新分配src播放下一首歌就很尴尬。

所以不要太依赖onCanplay。幸运的是,目前直接使用audio.duration似乎不会出现上面所说的currentTime渲染不及时的问题,所以还是先使用吧。

音频播放结束后,即onStop后,audio.play()无法再次播放,需要重新分配src

正常情况下,音频播放后,音频的src不变,应该可以再次播放()。但是在小程序里不行,你要重新分配src才能再播放,这应该是小程序的bug。

因此,我们需要判断暂停和停止的情况,并以不同的方式播放。正常情况下,音频暂停时,currentTime不为零,但结束时,currentTime为零。

因此,您可以通过currentTime(最好是一个自维护变量)来判断暂停和停止的情况。如果currentTime不是0,说明是暂停情况,可以使用play()。如果小于或等于0,重新分配src播放:

如果(当前时间){这。audio.play ()} else {this。audio.src=' xx.mp3'} mpvue不支持直接在模板上绑定函数

这是mpvue文档里写的,但是刚开始并没有很好的理解,而且还踩坑了,所以这里请大家提一下,避免不认识的同学长时间踩坑。

template div-for='(item,index)在list ' : key=' index ' { format item(item)} }/div/template script export default { data(){ return { list :[1,2,3]}}中,方法: { format item(item){ return ` I am $ { item } `}/script。上面的代码应该是日常vue中常用的,即把数据传递给方法进行处理,这在mpvue中是不支持的,会被编译成空字符串。

css3的一些功能可以安全地用在小程序中

例如高斯模糊

filter:模糊(50px);如果您想使用动画,请尝试用css动画替换wx.createAnimation

在实际使用中,wx.createAnimation其实很卡,性能也很差,所以在需要动画的时候建议尽量使用css。

小程序支持Css动画。过渡、动画和@关键帧都受支持。

例如,要制作一个始终旋转div的动画,可以比较两个版本:

Wx.createAnimation版本

原理:通过setInterval()不断更新div的旋转位置

template div class=' cover ' : animation=' animation data '/div/template script export default { data(){ return { animation data: ' ',animation: ' ',rotatecount : 0 0,timer: '' } },components: { },methods 3: { startRotate(){ this . timer=setInterval(()={ this . rotateAni(this . rotatecount)},100) },rotateAni (n) { if(!This.animation) {return} //每100毫秒旋转10度。动画。旋转(10 * n)。这一步。动画数据=这个。动画。export ()}},on show(){//if(!这个。动画){这个。动画=wx。createanimation()此。startrotate ()}},onready () {//if(!这个。动画){这个。动画=wx。createanimation()此。starrotate ()}},on hide(){//将在页面隐藏时执行,以避免频繁的setData操作。卸下这个。定时器clearinterval(这。timer)},在destroy()之前{//page,并且也停止这个。定时器clearinterval(这。timer)} }/脚本样式范围为lang=“SCS”。封面{ left: 20pxbottom: 70px边界半径:50%;背景# fff绝对位置:宽度: 50px;高度: 50px;background: rgba(0,0,0,0.2);box-shadow : 0px 2px 5px 0px rgba(0,0,0,0.2);border: 1px固体rgba(255,255,255,0.5);飞越:隐藏;z-index : 10000;}/style将css的@关键帧用于旋转动画

template div class=' cover ' : style=' cover style '/div/templatescriptexportdefault { }/script style scoped lang=' SCS '/定义一个名为rotate @ keyframes rotate {0%,100% {transform: rotate (0deg)的动画;} 100% { transform : rotate(360 deg);} } .封面{ left: 20pxbottom: 70px边界半径:50%;背景# fff绝对位置:宽度: 50px;高度: 50px;background: rgba(0,0,0,0.2);box-shadow : 0px 2px 5px 0px rgba(0,0,0,0.2);border: 1px固体rgba(255,255,255,0.5);飞越:隐藏;z-index : 10000;//使用动画:旋转4s线性无穷大;}/用js编写的style动画需要控制setInterval的间隔时间和旋转角度,很难调整。用css写动画很简单,性能比js好,代码少。

建议在使用css动画时打开硬件加速

为了让动画更流畅,想尽一切办法优化。虽然不知道会不会用,但是用了之后再聊【手动搞笑】。

硬件加速可以通过意志改变和转换:转换3d (0,0,0)来开启。我也不知道怎么用。具体用法,咱们百度谷歌。

will-change : auto;transform: translate3d(0,0,0);IPhoneX要求底部导航栏保留34px(68rpx)的高度。

由于无法在小程序中设置viewport-fit=cover,因此web中没有安全区域。目前主流的方法是通过wx.getSystemInfoSync()来判断是否为ipx,如果是,则以34px支持页面底部。

const RES=wx . getsysteminfosync()if(res.model.indexOf('iPhone X ')=0){ this . isipx=true }请注意,使用的是RES . model . indexof(' iPhone X ')。在开发者工具的iPhone X中,型号都等于iPhone X,但是在真机中经常得到的值是iPhone X GZxxx,也就是后面可能有一串东西,所以使用indexOf是比较稳定的,也适用于iPhone XR等型号。

由于还有其他安卓机的全屏,无法一一判断,而且部分安卓的全屏不使用iPhone底部的工具栏(没有冲突),所以只能判断iPhone X的情况,其他的全屏不需要预留底部。

至于整体屏幕布局的适配,需要通过使用flex布局或者获取屏幕的宽度和高度来慢慢调整。建议自适应处理使用flex布局。

无法触发for循环中的子组件单击事件

页面-父组件-子组件,子组件点击后,一个event $emit出来,发现无法触发。

这个bug一开始没有出现,但是偶尔会出现npm run build,然后检查原因。即使以后所有版本都回滚,npm start仍然会出现。好像不触发就会失控。这又是一个大坑,找问题,分组问人。那天晚上你下班回家的时候没有成功。

第二天继续学习,感觉可能是框架的原因。最后,我尝试升级mpvue版本,但这很正常。直接使用quick-strat项目的mpvue版本是2.0.0,mpvue和MPV UE-template-编译器可以通过升级到最新的2.0.6来解决。

事后看mpvue版本记录,确实是框架本身,发现了问题。

npm运行构建后,代码会报告一个错误,再次构建可能会报告其他错误

解决方法:没有找到原因,可能是因为引入了vant,打包的时候丢失了一些文件。再构建几次,或者重新启动applet开发工具。

mpvue中的created()钩子会在页面初始化时一起触发,所以尽量不要使用小程序生命周期的理解

进入销毁页面组件时,依次在加载、显示、就绪、装载前和装载时触发:

第一次进入销毁的子组件时,依次触发: onload、onready、beforemount和mount

第二次进入销毁的子组件时,将依次触发:加载、显示和就绪

当输入未被再次销毁的页面组件和子组件时,仅触发: onShow

在mpvue文档中,建议尽量不要使用小程序的生命周期。这应该是为了让项目更好的适应支付宝小程序和头条小程序,所以建议大家尽量不要使用某个小程序的api。

如果你的小程序只是一个微信小程序(不考虑与其他平台小程序的兼容性),我建议直接使用小程序的生命周期,而不是mpvue的生命周期。洞太多了。例如,在mpvue的创建周期中,所有页面都将在初始化期间执行,因此无法使用创建的周期。

未加载不会触发

applet和普通web开发的区别在于它的页面会被缓存。例如:

第1页从第1页跳到第2页,然后从第2页返回第1页。此时页面1还没有被销毁,不会触发onLoad重新渲染,而是直接使用之前的数据。从性能的角度来看,简单的返回不应该要求api获取数据进行重新渲染,这是正确的,也符合我们的预期。有时,当从第2页返回到第1页时,我们希望第1页重新获取数据进行渲染。例如,当您在第2页注销时,当您返回第1页时,您仍然会看到以前的数据。实际上,我们的期望是,既然我们已经注销,第1页的数据应该被销毁。在普通的web开发中,遇到上述问题时,我们可能会要求api在每次返回第1页时重新渲染最新的数据,牺牲一些性能来保证逻辑的正确性。

在mpvue中,我试图销毁第1页的onUnload()生命周期中的数据,但失败了。即使第2页注销并使用wx.reLaunch()再次刷它,也不会执行第1页的onUnload()生命周期。因此,可能无法执行onUnload(),因此建议谨慎使用。

最后,我们必须找到一种方法来控制第2页中第1页的数据销毁或保留。想到这,vuex就不自觉地出现了。如果第一页的数据由vuex控制,那么我可以在第二页使用vuex灵活管理其他页面的数据。

如果第2页注销,则销毁第1页的数据。如果不注销正常返回,页面1的数据仍然正常,可以实现灵活控制。

个人认为,vuex很少用于web开发,因为项目相对简单,不需要复杂的全局数据传输。但是在小程序中,建议全局使用vuex控制所有数据(当然一定要根据需求使用)。

摘要

第一次开发小程序,直接去mpvue。可能有些坑是很多同学总结出来的,有些坑可能是不熟悉造成的,但如果我一次都没踩过,可能就不够深了。

有两种坑很难啃:

框架本身的问题,比如mpvue2.0.0中的子组件不能触发事件的问题。开发者工具与真实机器运行环境不一致导致的坑。

如果真机和开发者工具不一致,可以按照以下步骤检查:

它可能是一个缓存,可以杀死以前的版本并再次运行。手机微信版本太低,api可能不支持。用wx.canIUse在手机上打印一些属性,比如上面的this.audio.src。您可以在真实机器上打印和调试代码。如果在手机上运行出现错误,可以在手机上开始调试。看看日志微信设计中的坑。如果百度下有相关案例和解决方案,可以遇到mpvue框架的问题:

搜索mpvue的问题,看看是否有相关的解决方案。尽量使用最新版本的框架。可能有些问题已经解决了。如果解决不了,建议想办法绕过,用另一种方法实现。以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:mpvue开发音频小程序踩坑建议详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。