数据层、业务逻辑层、服务处、控制层、展现层、用户
,小程序属于展现层
,一般还须要其余层次提供支持javascript
app.js,app.json,app.wxss
,前二者是必须存在再根目录下,app.wxss
能够不要php
通常位于pages
目录下,同一个目录下的四个文件必须同名a.wxml,a.js,a.wxss,a.json
,前二者是必须存在的,后二者能够不要css
app.json
文件中的window
配置项中内容提供App
方法来注册程序(只能注册一次),page
方法来注册页面html
document,window
等没法使用全部的代码都被打包为一份javascript
,在小程序启动时运行,直到销毁。相似ServerWorker
,因此逻辑层又称为AppServer
java
并非一个元素组件,仅仅是一个包装元素,不会在页面作任何渲染,只接受控制属性。嵌套组件的渲染必须用block或repeat
包装,不然可能会出现问题android
引入文件的三种方式:ios
import
方式引入的是模板文件,如<import src="a.wxml"/>
,不会嵌套引入;include
方式是将除模板以外的代码所有引入到当前位置,如<include src="h.wxml"/>
;@import
方式可引入外部wxss
文件,如@import a.wxss
。注意:必须放在最前面,放在代码后不会生效多数状况下二者的返回值时同样的,可是当组件嵌套时,而且内外层组件都定义了事件处理函数,那么在触发内存组件时,这两个对象的返回值就不太同样了web
建议使用小程序扩展的两种rpx
和rem
chrome
被绑定的数据必须在data
属性里先作定义,不然可能不会正常渲染json
view
和appServer
。其中view
线程负责页面的解析和渲染(包括wxml
和wxss
),appServer
线程负责运行js
。appServer
线程运行在jsCore
中(安卓下运行在X5
中,开发者工具中运行在nwjs
中)。因为js
并不运行在web-view
里,因此就没法操做BOM
和DOM
,这就是小程序没有window
全局对象的缘由Object
对象中,用this
访问注意:
app.onHide
注意:
onLoad => onShow => onReady
**一个完整的小程序执行的生命周期以下:
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:
<button open-type="share" class="btn" style="background-image: url(11.png);" plain="true" > </button> .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
默认没有长度限制
/n
问题view
组件不识别/n
,text
能够。保存的文本中有换行,若是读取的时候将数据放入view中换行没有效果,放入text中就行了。原则上text
标签与其中的内容不能有换行或空格,不然会有大片空白
wx.showModal
方法的换行问题:在文本中添加\r\n
,但须要在真机上才能生效,开发者工具不行
小程序中经过多个 
是没法正常显示多个空格的,解决方法:用中文全角空格部 门
(shift+space)
textarea问题
auto-height="true"
不设置maxlength=“-1”
,输入长度会遭限制;<textarea/>或<input/>
设置auto-focus
属性;textarea
苹果和安卓的显示高度不一致,不给textarea
设置宽度,则默认是300px
;auto-height
时,style.height
不生效,而且ios
和android
高度显示不一致button
的边框是用:after
方式实现的,用户若是在button
上定义边框会出现两条线,需用:after
的方式去覆盖默认值。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只能等官方优化,你们谨慎使用。
<live-player />’渲染失败,错误缘由: insertLivePlayer:fail:access denied
缘由:微信的权限里的相机和麦克风没有权限致使的,到手机 设置-应用-微信-权限里设置
input,textarea 能够经过标签的cursor-spacing属性设置键盘与输入框的距离
有嵌套关系的组件须要被循环渲染时,必定 要用block
或repeat
,不然会出现一些奇怪问题,如可能取不到item
对象的属性值等
data-id
必须小写。data-author-name
在e.currentTarget.dataset
中会自动转换authorName
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把文件下载到本地,而后再处理
能够把日期(年/月/日)存储到storage;在页面onLoad时,判断当前日期和storage存储的日期(转时间戳)是否相等,不然就视为次日
event
事件对象修修改dataset
属性值???试过好像不行
event
事件对象修修改class
类属性值???试过好像不行
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作上拉下拉刷新都须要注意这两个事件是会屡次调用的。须要一个标识符来拦截屡次调用
缓存问题
number、boolean、array、string、object 等
尽可能使用异步方式写入缓存,编码同步方式
;能够添加 try catch finally
处理 **注意:** 你在开发小程序过程当中,是否遇到,本身已经删除了体验版小程序,可是缓存依然存在? 那是由于,同一个小程序的开发版、体验版、线上版的缓存是共用的,你须要同时删除这三个版本的小程序,缓存才会被删除。 参考:[小程序缓存踩过的坑](https://blog.csdn.net/weixin_42133469/article/details/81875125)
设置当前涂层和弹框的 @touchmove.stop="func"
便可,不要在func
内添加preventDefault 或 cancelBabel
(不支持)
onNetworkStatusChange
网络由正常状态变为断开状态时,发布帖子会报错;这时网络又恢复正常,点击发布按钮却没反应,也没触发请求。
解决方案:在注册小程序的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; } ... ```
wepy
相关wepy
中的this.$apply()
方法通常用于组件从头传值的.sync
中,其余状态更新的地方不必添加该方法
组件问题
wepy
的组件是静态组件,是以ID
做为惟一标识,每个ID都对应一个组件实例,当页面引入两个相同ID的组件时,这两个组件共用同一个实例与数据,当其中一个组件数据变化时,另一个也会一块儿变化。若是须要避免这个问题,则须要分配多个组件ID和实例。
components = { //为两个相同组件的不一样实例分配不一样的组件ID,从而避免数据同步变化的问题 ErrorComponent: ErrorComponent, ExceptionComponent: ErrorComponent };
组件传值问题
object,array
等,但须要先序列号;注意:若是传递是object
,内部不能再有嵌套的复合数据类型了,负责子组件没法正确渲染(手机),array
类型的能够不要再在子组件中修改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天
其余: