微信小程序开发总结

架构分析

  • 软件应用架构包括:

    数据层、业务逻辑层、服务处、控制层、展示层、用户,小程序属于展示层,通常还需要其他层次提供支持

  • 主体文件:

    app.js,app.json,app.wxss,前两者是必须存在再根目录下,app.wxss可以不要

  • 页面文件:

    一般位于pages目录下,同一个目录下的四个文件必须同名a.wxml,a.js,a.wxss,a.json,前两者是必须存在的,后两者可以不要

  • 其他文件:其他静态资源可以放在目录下的任何位置
  • 页面的配置文件 只能配置全局app.json文件中的window配置项中内容
  • 小程序属于表现层,但又可以细分为逻辑层和视图层
  • 注册

    提供App方法来注册程序(只能注册一次),page方法来注册页面

  • 框架并非运行在浏览器中,一些document,window等无法使用
  • 编译

    所有的代码都被打包为一份javascript,在小程序启动时运行,直到销毁。类似ServerWorker,所以逻辑层又称为AppServer

  • block

    并不是一个元素组件,仅仅是一个包装元素,不会在页面做任何渲染,只接受控制属性。嵌套组件的渲染必须用block或repeat包装,否则可能会出现问题

  • 模板
    模板拥有自己的作用域,只能使用data传入的数据
  • 引入文件的三种方式:

    1. import方式引入的是模板文件,如,不会嵌套引入;
    2. include方式是将除模板之外的代码全部引入到当前位置,如
    3. @import方式可引入外部wxss文件,如@import a.wxss。注意:必须放在最前面,放在代码后不会生效
  • target与currentTarget对象区别:

    多数情况下两者的返回值时一样的,但是当组件嵌套时,并且内外层组件都定义了事件处理函数,那么在触发内存组件时,这两个对象的返回值就不太一样了

  • 尺寸单位

    建议使用小程序扩展的两种rpx和rem

  • 数据绑定

    被绑定的数据必须在data属性里先做定义,否则可能不会正常渲染


线程架构

  • 每个小程序分为2个线程,view和appServer。其中view线程负责页面的解析和渲染(包括wxml和wxss),appServer线程负责运行js。appServer线程运行在jsCore中(安卓下运行在X5中,开发者工具中运行在nwjs中)。由于js并不运行在web-view里,所以就无法操作BOM和DOM,这就是小程序没有window全局对象的原因

生命周期

app生命周期——始终优先于page声明周期

  • onLaunch:小程序初始化完成就调用,只被触发一次
  • onShow:小程序启动、从后台进入前台显示,被触发
  • onHide:小程序从前台进入后台,被触发
  • onError:小程序出错、api调用失败、被触发
  • -onPageNotFound:打开的页面不存在,被触发
  • 其他:开发者可以添加任意函数或数据到Object对象中,用this访问

注意:

  • App() 必须在 app.js 中注册,且不能注册多个
  • 不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就可以拿到 app 实例
  • 不要在 onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成
  • 通过 getApp() 获取实例之后,不要私自调用生命周期函数

page生命周期

  • onLoad: 页面在加载时,只被触发一次
  • onReady: 页面初次渲染完成,只被触发一次
  • onShow: 页面显示时,被触发
  • onHide: 页面隐藏时,被触发(触发左上角的退出箭头时,仅触发app.onHide
  • onUnload: 生命周期函数--监听页面卸载,只被触发一次
  • onPullDownRefresh: 页面相关事件处理函数--监听用户下拉动作
  • onReachBottom: 页面上拉触底事件的处理函数
  • onShareAppMessage: 用户点击右上角转发
  • onPageScroll: 页面滚动触发事件的处理函数
  • onTabItemTap: 当前是 tab 页时,点击 tab 时触发
  • 其他 Any 开发者可以添加任意的函数或数据到 object 参数中,在页面的函数中用 this 可以访问

注意:

  • 执行顺序: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...退出小程序)

视图层注意事项

  • 请使用官方提供的wxss选择器,其他选择器可能也没问题,但是不推荐。
例如`.cls1 .cls2`级联样式,微信团队说会破坏组件结构,级联最终会被取消,未来会推出新的方案。
  • 所有的组件和属性都需要使用小写

踩坑指南

网络相关问题

  • 无法抓到请求

    charles或fiddler抓取不到开发者工具的请求,打开代理127.0.0.1:8888

  • 提示非法域名

    一般情况都是出现了不在合法域名中的域名,打开开发者工具中的“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”

  • Get和Post请求的返回数据不支持二进制流

    小程序支持通过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;
    }
 } 
  ```
  • input长度

    value值的默认最大长度是140个字符(不包括空格),如果长度长度超过最大长度,需要设置maxlength=-1即可。

    H5中input的value默认没有长度限制

  • text组件的/n问题

    view组件不识别/n,text可以。保存的文本中有换行,如果读取的时候将数据放入view中换行没有效果,放入text中就好了。原则上text标签与其中的内容不能有换行或空格,否则会有大片空白

    wx.showModal方法的换行问题:在文本中添加\r\n,但需要在真机上才能生效,开发者工具不行

  • 多个空格的问题

    小程序中通过多个 是无法正常显示多个空格的,解决方法:用中文全角空格部  门(shift+space)

  • textarea问题

    • 设置了auto-height="true"不设置maxlength=“-1”,输入长度会遭限制;
    • 页面中只能有一个