数据层、业务逻辑层、服务处、控制层、展示层、用户,小程序属于展示层,通常还需要其他层次提供支持
app.js,app.json,app.wxss,前两者是必须存在再根目录下,app.wxss可以不要
一般位于pages目录下,同一个目录下的四个文件必须同名a.wxml,a.js,a.wxss,a.json,前两者是必须存在的,后两者可以不要
提供App方法来注册程序(只能注册一次),page方法来注册页面
所有的代码都被打包为一份javascript,在小程序启动时运行,直到销毁。类似ServerWorker,所以逻辑层又称为AppServer
并不是一个元素组件,仅仅是一个包装元素,不会在页面做任何渲染,只接受控制属性。嵌套组件的渲染必须用block或repeat包装,否则可能会出现问题
引入文件的三种方式:
多数情况下两者的返回值时一样的,但是当组件嵌套时,并且内外层组件都定义了事件处理函数,那么在触发内存组件时,这两个对象的返回值就不太一样了
建议使用小程序扩展的两种rpx和rem
被绑定的数据必须在data属性里先做定义,否则可能不会正常渲染
注意:
注意:
**一个完整的小程序执行的生命周期如下:
app.onLaunch => app.onShow => page1.onLoad => page1.onShow => page1.onReady (打开程序,第一个页面page1加载完成) => page1.onHide => page2.onLoad => page2.onShow => page2.onReady (从第一个页面新打开page2) => page2.onUnload => page1.onShow => ... => app.onUnload (关闭page2,返回page1...退出小程序)
例如`.cls1 .cls2`级联样式,微信团队说会破坏组件结构,级联最终会被取消,未来会推出新的方案。
charles或fiddler抓取不到开发者工具的请求,打开代理127.0.0.1:8888
一般情况都是出现了不在合法域名中的域名,打开开发者工具中的“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”
小程序支持通过post获取小程序码(有点像菊花)。尝试通过wx.request向微信服务器获取小程序码的图片,结果发现返回的结果无法显示。开始怀疑代码有问题,调试之后,发现微信服务器返回的结果正确,而小程序会自动把二进制结果转码。更郁闷的是,这种转码丢失了文件内容,并且转换是不可逆的。
于是,我们改方案,把服务器当中转站,让小程序使用wx.downloadFile从服务器下载图片。在收到小程序下载图片的请求之后,服务器直接和微信服务器获取小程序码的图片,然后以附件的形式返回给小程序。
参考:小程序开发,那些我们跳过的坑
断网或者与正常网络互相切换时问题
如果需要根据网络状态判断是否发送异步请求,可以通过官方文档提供的onNetworkStatusChange和``两个方法来处理
wx.getNetworkType({
success(res) { if(res.networkType === 'none') { globalData.netNotConnected = true; } }
})
wx.onNetworkStatusChange(res => {
if (res.isConnected) { globalData.netNotConnected = false; } else { globalData.netNotConnected = true; tip.alert("网络已断开,请连接后重试"); }
});
无法使用本地的字体文件,必须使用网络地址
background-image背景图片不支持本地图片,只能用网络url或者base64;本地图片要用image标签才行
button样式
小程序的button是用伪元素实现的,去掉其默认样式需要用button::after{ border: none; }
设置背景图片
方法1:
.btn{ width: 30rpx; height: 30rpx; padding: 0 20rpx; position: absolute; right: 32rpx; top: 0; bottom: 0; margin: auto; background-size: 30rpx 30rpx; background-repeat: no-repeat; border: none; }
参考:https://www.jianshu.com/p/b1d8a62da876 - 方法2: ``` .btn { position: relative; &::after { display: inline-block; content: ""; position: absolute; top: 0; right: 20rpx; left: 0; background: url(11.png) no-repeat 0 0; background-size: 715rpx 120rpx; background-size: 100% 100%; z-index: -1; } } ```
value值的默认最大长度是140个字符(不包括空格),如果长度长度超过最大长度,需要设置maxlength=-1即可。
H5中input的value默认没有长度限制
view组件不识别/n,text可以。保存的文本中有换行,如果读取的时候将数据放入view中换行没有效果,放入text中就好了。原则上text标签与其中的内容不能有换行或空格,否则会有大片空白
wx.showModal方法的换行问题:在文本中添加\r\n,但需要在真机上才能生效,开发者工具不行
小程序中通过多个 是无法正常显示多个空格的,解决方法:用中文全角空格部 门(shift+space)
textarea问题
scroll-view
清除黑色滚动条(竖向滚动时)
::-webkit-scrollbar { width: 0; height: 0; color: transparent; }
参考:小程序填坑之路
cover-view
由于小程序里面video标签的层级是最高的无法覆盖。所以cvoer-view应运而生。它就是用于盖在video标签上面,进行对video标签的周遭加以装饰的利器。 例如在cover-view上面使用相对定位,当video标签大小发生变化的时候,cover-view上面的元素就乱七八糟。 又譬如圆角的不起效等等。 具体的问题大家可以在开发者社区看看。[cover-view定位问题](https://developers.weixin.qq.com/search?action=list&t=search/index&search_type=1&key=cover-view&token=&lang=zh_CN) 避坑方法:尽量在cover-view上不使用定位,其他的bug只能等官方优化,大家谨慎使用。
原因:微信的权限里的相机和麦克风没有权限导致的,到手机 设置-应用-微信-权限里设置
input,textarea 可以通过标签的cursor-spacing属性设置键盘与输入框的距离
有嵌套关系的组件需要被循环渲染时,一定 要用block或repeat,否则会出现一些奇怪问题,如可能取不到item对象的属性值等
objectFit去除小程序视频标签的黑边(没试过)
swiper问题
**问题2:** 轮播图显示异常问题:A页面有`swiper`图片轮播,跳转到B页面编辑并删除某张轮播图片,再返回A页面后,轮播图显示空白,添加新图片时没问题;初步猜测:返回A页面后,`swiper`的`current`属性的当前值状态值指向不存在导致。但在A页面`onShow`时重置`current`值也不行,暂没找到原因 1. 省市县镇级联选择时,当有多个`swiper-item`时,点击第二个及以后的省获取市时显示空白 解决方法:在点击第二个`swiper-item`里的省获取市之前先把`swiper`组件重置,如设置渲染条件先不让他渲染,获取到市数据后再设置条件让`swiper`组件渲染出来 1. `swiper`滑动过一次后,无法再动态的设置`current`的值解决方案 给`swiper`添加`change`监听事件,当滑动`swiper`时通过`e.detail.current`记录`current`,下次再返回时设置`current`为上次保存的值。 参考:[swiper bug, swiper滑动过一次后,无法动态改变current值](https://openclub.alipay.com/read.php?tid=2919&fid=51)
canvas问题
canvas层级最高,其他元素无论z-index设置多大,都不能盖在canvas上,解决方法:让canvas定位后设置比较大的偏移值,或设置hidden
绘图时的图片必须是已经下载好的图片,不能使用网络图片或base64,可以用微信提供的getImageInfo或downloadFile,示例:
async createPoster() { const imgPromise1 = return new Promise((resolve, reject) => { wx.getImageInfo({ src, success(res) { resolve(res); }, fail(error) { reject(error); } }) }); Promise.all([imgPromise1, imgPromise2]).then(res => { const [ res1, res2 ] = res; ... const ctx = wx.createCanvasContext('poster-canvas-id'); ctx.drawImage(res1.path, x, y, ...); }) }
海报(二维码)
手机扫描分享的海报二维码,只能跳转到小程序线上版本,可以通过抓包获取跳转时的启动参数,放到开发者工具中模拟线下环境跳转
如:通过scene值来实现:手机扫码生成海报二维码,抓包这个请求https://activity.12345.com/wxa/town/load?scene=hvORN4dgYy,记下这个scene值,在开发者工具中配置路径'pages/index/index' 参数scene=hvORN4dgYy即可 原理:getAppCode方法中,会把页面加载所需要的参数作为scene值来获取二维码;当扫描二维码时,这个二维码中含有scene值,先进入XX首页时会通过上面那个抓包请求获取这个scene,然后从scene中解析并调整到pagetype,从而先通过跳转首页后再跳转到指定的页面
其他 - Canvas和Image对图片的各种不支持
在开始的版本中,我们准备在Canvas上直接绘制二维码,接着使用wx.canvasToTempImage函数保存为image文件,然后通过Image组件加载。
经过调试,一切顺利。运行的时候呢,发现有时候在绘制完图片之后,调用wx.canvasToTempImage函数失败。这种情况在调试无法重现,运行的时候偶尔出现,不稳定。
仔细检查了代码,没问题啊。Google之后,有网友提出了解决方案,在drawImage完成之后,最好等3秒钟再调用wx.canvasToTempImage,以保证保存成功。
最初的方案中,我们自己生成二维码,后来为了兼容微信的“扫一扫”功能,我们决定改用小程序码。
开始,我们把Image的src设置为Base64格式,从服务器上通过request获取图片的Base64编码。小程序开发工具和iPhone上面测试都没有问题,唯独Android手机上无法正常显示图片。哦,原来在Android上,Canvas和Image都不支持Base64图片。可是...小程序开发文档中并没有这方面的说明啊。
怎么解决Android手机上的这个问题呢?如果把Image改成URL形式呢,小程序无法保存图片,以致即使是相同的图片,每次都要从服务器获取,这又加重了服务器的负担。这样吧,使用wx.downloadFile把文件下载到本地,然后再处理
参考:Canvas和Image对图片的各种不支持
可以把日期(年/月/日)存储到storage;在页面onLoad时,判断当前日期和storage存储的日期(转时间戳)是否相等,否则就视为第二天
试过好像不行
试过好像不行
tabBar里面的图标 只能是本地图片,不能是网络图片,否则无法显示。至少2个,最多5个
路由跳转问题
----------- - navigateTo, redirectTo 只能打开非 tabBar 页面。 - switchTab 只能打开 tabBar 页面。 - reLaunch 可以打开任意页面。 - 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。 - 调用页面路由带的参数可以在目标页面的onLoad中获取。 ----------- - **注意:最多跳转5个页面** - 在路由跳转的时候,模拟器偶尔会系统报错。频繁跳转出现概率比较高,但仅仅在模拟器出现。可以无视 **经过测试,因为页面跳转是有动画时效的,在动画进行中当前页面还能操作。如果双击当前跳转按钮机会进行两次跳转。第二次点击的时候小程序内置的路由栈是已经定位到了新的页面了,而这时候在按照原来的路由栈去定位当前页面,因此会报错。所以页面跳转按钮需要进行短时间多次点击的限制** 详见:[小程序路由](https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html)
bindscrolltoupper 还是 bindscrolltoupper做上拉下拉刷新都需要注意这两个事件是会多次调用的。需要一个标识符来拦截多次调用
缓存问题
**注意:** 你在开发小程序过程中,是否遇到,自己已经删除了体验版小程序,但是缓存依然存在? 那是因为,同一个小程序的开发版、体验版、线上版的缓存是共用的,你需要同时删除这三个版本的小程序,缓存才会被删除。 参考:[小程序缓存踩过的坑](https://blog.csdn.net/weixin_42133469/article/details/81875125)
设置当前涂层和弹框的@touchmove.stop="func"即可,不要在func内添加preventDefault 或 cancelBabel(不支持)
网络由正常状态变为断开状态时,发布帖子会报错;这时网络又恢复正常,点击发布按钮却没反应,也没触发请求。
解决方案:在注册小程序的onLaunch中通过wx.onNetworkStatusChange监听网络变化,同时把该状态存储到globalData全局变量中;当发帖时,首先判断网络状态,如果是断网的情况,就给出toast提示并禁止发布;如果是网络正常,就正常发布。这样即可解决断网又联网时导致不能发布的问题,示例:
// app.wpy ``` onLaunch() { wx.onNetworkStatusChange(res => { if (res.isConnected) { globalData.netNotConnected = false; } else { globalData.netNotConnected = true; tip.alert("网络已断开,请连接后重试"); } }); } ``` // formSubmit.wpy 表单提交 ``` if(globalData.netNotConnected) { tip.alert("网络已断开,请连接后重试"); return; } ... ```
Java PropertyChangeListener - 编程问答
wepy中的this.$apply()方法一般用于组件从头传值的.sync中,其他状态更新的地方没必要添加该方法
组件问题
wepy的组件是静态组件,是以ID作为唯一标识,每一个ID都对应一个组件实例,当页面引入两个相同ID的组件时,这两个组件共用同一个实例与数据,当其中一个组件数据变化时,另外一个也会一起变化。如果需要避免这个问题,则需要分配多个组件ID和实例。
components = { //为两个相同组件的不同实例分配不同的组件ID,从而避免数据同步变化的问题 ErrorComponent: ErrorComponent, ExceptionComponent: ErrorComponent };
组件传值问题
不要再在子组件中修改props中属性的数据类型,否则当该属性需要频繁获取时,页面会出现抖动,体验极差(如省市县镇的级联选择时,当前显示的areaData都是通过props中的areaData获取时,不能在子组件中修改其数据类型)
... props = { areaData: { type: String, default: "" } } computed = { this.areaData = JSON.parse(areaData); // 不可以,页面抖动 this.$apply(); } ...
1.模拟器和真机的差异
在模拟器上表现正常的,在真机未必正常,问题也很多。譬如
- 动画的使用 - cover-view上面使用定位 - wepy 组件传值 - canvas定位、绘图 - 背景图片路径
原因:造成这些错乱主要是pc端和移动端不同的内核导致的。 避坑方式:开发过程中,要时不时地用真机也看一下效果。
重启开发者工具;
描述:凡是公众平台服务端的修改,都需要重启开发者工具才能生效,包括https域名设置,开发者添加,appid使用,等等
文件夹不是空文件夹
以iphone6的rpx来进行小程序的布局最为方便,iphone6的宽度是750rpx
小程序不支持模糊匹配,只能精确搜索
单词设置的数据大小不能超过1024KB,否则会崩溃
校验
var wxReg=new RegExp("^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$") //微信号正则验证 var qqReg=new RegExp("[1-9][0-9]{4,}") //QQ号正则验证 var phReg=new /^1[345678]\d{9}$/ //手机号正则验证 var nameReg=new RegExp("^[\u4e00-\u9fa5]{2,4}$") //2-4位中文姓名正则验证
引入iconfont问题
H5方式:
@font-face {font-family: "iconfont"; src: url('iconfont.eot?t=1485242349767'); /* IE9*/ src: url('iconfont.eot?t=1485242349767#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('iconfont.woff?t=1485242349767') format('woff'), /* chrome, firefox */ url('iconfont.ttf?t=1485242349767') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('iconfont.svg?t=1485242349767#iconfont') format('svg'); /* iOS 4.1- */ } .iconfont { font-family:"iconfont" !important; font-size:16px; font-style:normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
小程序使用这种方式无法引入字体,解决方案如下:
- 进入iconfont选择自己需要的icon,并且下载到本地,找到后缀名为.ttf的文件 - 打开https://transfonter.org/,将字体文件转化成base64的格式 - 转化无完成后将生成的stylesheet.css拷贝到微信小程序项目中,通过@import方式引入,在需要引入的地方 ``` #icons:before{ font-family: "iconfont"; /* color: red; */ font-size: 40rpx; content: "\e60b" } ``` 参考:[微信小程序踩坑日志](https://blog.csdn.net/marko_zheng/article/details/79130076)
分享相关
小程序支持扫二维码进入,但不支持长按识别
授权和登录是两回事。登录是用户无感知的,获取到code 和后端通信获得openid来定位用户。而授权才能获取用户头像和名字等信息
小程序第一次提交审核的时间比较后面的长,第一次审核时间一般1-2天
其他: