强烈推荐的几个开发微信小程序的技巧,简单实用的还原,希望对大家有所帮助。如果真的对大家有帮助,别忘了点个赞哦#127775;~微信开发者工具版本:1.03.2006090(2020-06-19)基础库版本:v2.12.1(2020-08-04)1.开发中可能遇到的Pitfalls和Tips本来想写个小trick的,结果总结了一堆坑。在上手之前,我无法想象微信小程序的开发体验会如此糟糕,如此糟糕。从微信开发,从阅读器工具到所谓的“新语言”,有一种强烈的半成品感五即视觉,真是让我emmm...另外,我发现大部分小程序网上的文章都是如何使用和如何避免陷阱的实用文章,而不是技术文章,这也从侧面反映了小程序的陷阱。在最初开发微信小程序的时候,我一直在问“腾讯这么有技术人才,为什么要推出这样的拉鸡?”这样的问题。社区在两三年前就提过很多弱智反人类的东西,官方回复说正在修复,但是几年过去了,还是没有消息。官方回复依旧是冷冰冰的“反馈”😤微信开发者工具频繁热更新不工作甚至白屏,重新编译也不行。必须强行退出后才能重新打开;和上一个类似,有时候有点样式错误,整个预览都是一片空白,调试器也没有说是哪里出了问题,只能强行退出后才能再次打开;和上一个类似,调试器报的错往往是无用的,驴头不对,很难定位问题;Android端的自定义Tabbar在下拉刷新的时候,也会随着屏幕一起下移,是一个无法绕过的bug。自定义Tabbar样式写完后,我又改成了内置的Tabbar!导入路径不支持绝对路径。比如你要引用utils/fetch.js,你必须慢慢../指向任何组件中的根目录,不管它有多深。同样,@import只能导入.wxss文件中的文件使用相对路径,所以会出现../../../../../../utils/fetch.js之类的东西;6.静态资源路径不能有汉字,无法加载汉字;7、.wxs文件不支持ES6,只能使用蹩脚的ES5写法;8..wxml只能导入.wxs文件,不能导入.js文件???9、模板{{}}连方法都执行不了,只能处理+-*/等简单操作。如果数据需要过滤,需要在.js文件中预先格式化,然后逐个setData。比如经常写的[2,3,4].includes(type),连运行都跑不了!10、.wxs文件中不能使用Date对象,所以不能使用newDate(),只能使用蹩脚的getDate方法。正则表达式也是如此。生成正则对象需要使用getRegExp函数getRegExp(pattern[,flags]);11、.wxs可以调用其他.wxs文件,只需要调用.wxs文件,导入的文件必须使用相对路径;12..setData甚至懒得去合并一个对象,如果data:{a:{b:1,c:1}},那么setData({a:{b:2}})会失去a.c的值,这真的很烦人,需要setData({['a.b':2]});为NaN,因为IOS的Date构造函数不支持2018-04-26格式的日期,必须转为2018/04/26格式才能正常显示;不出门,右上角的三个点enabledebug打开“开发与调试”后,莫名其妙就可以发送请求了。很多手机都是这种情况。我不知道真相。-promise-pro,记得带上-s或者--production,否则构建不成功。npmi-Swx-promise-pro然后在app.js中:import{promisifyAll}from'wx-promise-pro'promisifyAll()//promisifyallwxapiApp({...})之后就可以正常使用了:wx.临。showLoading({title:'Loading',mask:true}).then(()=>console.log('inpromise~'))2.2自己实现其实我们可以自己实现这样一个库。原理很简单。以原生API的wx.request为例://原生API使用wx.request({url:'',//请求的urldata:{},//参数方法:'',//post,getsuccess:res=>{//请求成功回调函数,res为回调参数},fail:res=>{//请求失败回调函数,res为回调参数}})如果我们做Promise,调用方法应该是://Promiseization后的预期用法wx.pro.request({url:'',//requestedurldata:{},//parametermethod:''//post,get}).then(res=>{//request成功回调函数,res为回调参数}).catch(res=>{//请求失败回调函数,res为回调参数})然后then函数返回一个Promise对象,这样这个函数就可以连续链式调用方法调用,所以首先Promise对象需要是新的:functionrequest(opt){returnnewPromise((resolve,reject)=>{wx.request({...opt,success:res=>{resolve(res)},fail:res=>{reject(res)}})})}我们可以进一步改进这里的代码,因为传递的参数是in这里的success和fail只是resolve和reject方法执行的,所以直接传入resolve和reject方法即可。另外,由于其他小程序的原生API格式是一致的,我们可以使用柯里化的方式来处理其他需要Promised的API:functionpromisify(api){return(opt={})=>{returnnewPromise((resolve,reject)=>{api({...opt,fail:reject,success:resolve})})}}然后,将柯里化的方法执行结果作为新的基于promise的API挂载到wx中。在pro对象上://Promise指定的APIwx.pro.request=promisify(wx.request)//使用wx.pro.request({...}).then(...)然后为了我们方便使用其他方法,可以将wx对象上可以Promise的方法,如request、scanCode、showToast、getUserInfo等方法,一一循环挂载到wx.pro对象中。使用的时候直接wx.pro.xx就可以了,因为这个方法执行返回的Promise是一个Promise,所以可以像其他任何Promise一样使用。其实在不知不觉中,我们自己实现了wx-promise-pro的源码。这个库的核心代码是上面的几行🥳2.3在项目中使用完以上工具后,我们就可以在项目中使用了。为了不在项目中传播wx.request或者wx.pro.request,这里可以简单封装一下。新建两个文件如下://utils/api/fetch.js封装请求方法和请求拦截器constapp=getApp()constBaseUrl='http://172.0.0.1:7300/mock'constTokenWhiteList=['/app/user/get-by-code'//不需要认证的Apis在这里手动添加]/***设置请求拦截器*@paramparams请求参数*/constfetch=(params={})=>{//interceptor逻辑if(!TokenWhiteList.includes(params.url)){params.header={'content-type':'application/json',//默认值'token':app.globalData.token||''}}if(params.url.startsWith('/')){//拼接完成URLparams.url=BaseUrl+params.url}//返回承诺returnwx.pro.request({...params}).then(({data:{code,message,data}})=>{//...各种异常逻辑处理//code20000与后端约定好后,正常返回if(code===20000)returnPromise.resolve(data)returnPromise.reject(message)})}export{fetch}然后将所有的API封装到单独的文件集中管理://utils/api/apis.jsencapsulates所有请求APIimport{fetch}from'./fetch'/*根据微信码获取用户信息*/constappUserGetByCode=({code}={})=>fetch({url:'/app/user/get-by-代码',数据:{代码}})/*扫码登录*/constappUserQrLogin=({qrCode}={})=>fetch({method:'POST',url:'/app/user/qr-login',data:{qrCode}})/*个人信息*/constappUserInfo=()=>fetch({url:'/app/user/info'})/*系统参数获取、数据字典*/constappSysParamListByParam=()=>fetch({url:'/app/sys-param/list-by-param'})/*数据字典所有*/constappSysParamListAll=()=>fetch({url:'/app/sys-param/list-all'})export{appSysParamListAll,//数据字典allappSysParamListByParam,//获取系统参数,数据字典appUserGetByCode,//根据微信码获取用户信息appUserQrLogin,//扫码登录appUserInfo//个人信息}在其中导入即可你想使用API??:import*asApifrom'../../utils/api/apis.js'//相对路径//usageApi.appSysParamListAll().then(({dataList})=>this.upData({sysParamList:dataList})).then(()=>{constkeyList=this.data.sysParamList.map(T=>T.key)this.upData({keyList,formData:{keys:keyList}})})使用起来很舒服,这里用到了upData,也就是我下面要介绍的内容。是我强烈推荐的小程序工具~🥳3.setState修改要修改的数据中对象的属性。在小程序中,不能直接操作数据。需要使用setData函数。鉴于开发微信小程序时使用setData体验不佳,我使用了一个库函数wx-updata。这个库函数在开发的时候对我帮助很大,在此推荐给大家。3.1为什么要用wx-updata在用setData的时候,是不是有时候会觉得不舒服,举个简单的例子://yourdatadata:{name:'CrayonShin-chan',info:{height:140,color:'yellow'}}如果想修改info.height为155,如何使用setData://这会让info中的其他属性消失this.setData({info:{height:155}})//需要把info取出来目的。修改后,整个setDataconst{info}=this.datainfo.height=155this.setData({info})看起来并没有太复杂,但是如果数据是大对象,肯定要更深一些,不同的对象和数组项一一变化:data:{name:'蜡笔小新',info:{height:140,color:'yellow',desc:[{age:8},'我喜欢大象的歌','小boy',{dog:'小白',color:'white'}]}}比如某个需求,需要将info.height修改为155,修改info.desc的item0的agearrayto12,item3的颜色是灰色?//先取出要改变的对象,改变数字后setData返回const{info}=this.datainfo.height=155info.desc[0].age=12info.desc[3].color='gray'this.setData({info})//或者像某些文章介绍的那样,可读性差,实用性不强this.setData({'info.height':155,'info.desc[0].age':12,'info.desc[3].color':'gray'})以上两种方法在我们日常的小程序中经常用到。和其他web端框架相比,很蹩脚,一个厚厚的半成品,感觉不知所措,有没有这样的方法:this.upData({info:{height:155,desc:[{age:12},,,{color:'gray'}]}})这个方法会帮助我们深度改变嵌套对象中对应的属性值,跳过数组中不想改变的项,只设置我们提供的属性值和数组项。岂不是省略了很多蹩脚的代码,可读性也是极好的呢。这就是为什么我在在线项目中使用wx-updata而不是setData的原因。wx-updata的原理其实很简单。例如:this.upData({info:{height:155,desc:[{age:12}]}})//会自动转换为如下格式,//this.setData({//'info.height':155,//'info.desc[0].age':12,//})原来我们需要手动做这个转换工作,现在wx-updata帮我们做了,不会吧太棒了!3.2如何使用wx-updata一般情况下,我们可以直接将方法挂载到Page的构造函数中,这样我们就可以像使用setData一样在Page实例中使用upData了://mountimport{app.js中的updataInit}from'./miniprogram_npm/wx-updata/index'//你的库文件路径App({onLaunch(){Page=updataInit(Page,{debug:true})}})//如何在页面代码中使用这个.upData({info:{height:155},desc:[{age:13},'帅哥'],family:[,,[,,,{color:'gray'}]]})部分边框可能已进一步修改在Page对象上制作,直接替换Page的方式可能不是很好。wx-updata也对外暴露了工具方法,用户可以直接在页面代码中使用工具方法进行处理://import{页面代码中objToPath}from'./miniprogram_npm/wx-updata/index'//你的库文件pathPage({data:{a:{b:2},c:[3,4,5]},//自己打包看看upData(data){returnthis.setData(objToPath(data))},//在你的方法或生命周期函数中yourMethod(){this.upData({a:{b:7},c:[8,,9]})}})鉴于修改时可能跳过数组中的空槽数组中的指定项,wx-updata提供了EmptySymbol类型的替换和数组的对象路径方法。有兴趣的可以看看wx-updata的文档,也可以参考<开发微信小程序,我为什么放弃setData而使用upData>这篇介绍文章另外,使用wx-updata也可以使用原来的setData,尤其是有时候需要清空数组的时候,可以灵活使用获取更好的结果。小程序开发经验,祝你小程序开发愉快🤣4、使用scss编写样式4.1Webstorm配置方法关于蹩脚的.wxss样式,我使用webstorm的文件监视工具来监视scss文件的变化,实时编译成.wxss文件,我觉得比较好用,这里给大家分享下我的配置:然后记得在.gitignore文件中添加忽略的样式:*.scss*.wxss.map这样上传到git的时候就不会上传scss文件了~当然,如果你的团队成员需要scss,建议用git上传的时候加上scss文件。这样设置后,本地会出现一个组件如下,其中需要注意.js、.json、.scss、.wxml文件,另外一个.wxss文件会在你更改后自动生成并更新.scss文件。而.wxss.map是插件自动生成的映射关系,不用管。如果你没有使用webstorm,可以直接执行命令sass--watchindex.scss:index.wxss-sexpanded。如果关闭命令行,sass命令不会监听文件变化再编译,所以最好使用编辑器插件。同样,也可以使用less、stylus等预编译语言。4.2VisualStudioCode配置方法万能的VSC当然也可以做这个功能,搜索下载插件easysass,然后在setting.json中修改/添加配置:"easysass.formats":[{"format":"expanded","extension":".wxss"},{"format":"compressed","extension":".min.wxss"}]上面expanded是编译后的.wxss文件,下面compressed是压缩后的.wxss样式文件,如果不需要下面的配置,可以把下面的配置去掉,然后在.wxss里面添加要忽略的中间样式。其他同上,至此在小程序开发中就可以愉快的使用scss了~5.使用iconfont图标字体iconfont是Web开发中最常用的灵活图标字体工具,下面介绍如何在微信小程序中使用iconfont图标。先找到你要用的图标,点击购物车,下载到本地。是本地下载的压缩包。解压后,将iconfont.css文件复制到微信小程序的styles文件夹中(也可以放在自己喜欢的地方,比如字体),并将后缀改为.wxss,在app.wxss中引入样式:@import》样式/iconfont.wxss";那么就可以在.wxml中使用刚才添加的图标,Web使用i标签,小程序使用text标签:
