小程序 Tip | 基础概述

框架结构

一般软件的应用架构:
  • 微信小程序是一套系统的展示层;

小程序项目目录结构

  • wxml 类比 html 页面描述文件
    js 页面逻辑文件
    wxss 类比 css 样式表文件

  • 主目录中,
    3个app开头的文件就是微信小程序框架的主描述文件,
    这3个文件不属于任何页面;

  • pages目录下还有2个子目录——index、logs:

    每个子目录中保存着一个页面的相关文件 —— 通常是4种不同扩展名的文件,
    分别是页面中的逻辑文件、页面结构文件、样式表文件、配置文件;
    为了减少开发时的配置项,框架特别约定描述页面的这4个文件必须具备相同的路径和文件名

主体文件

一个微信小程序的主体部分 由3个文件组成,
这个3个文件必须放在项目的主目录中,
3个文件的名称也是固定的(app);

  • app.js
    小程序的主逻辑文件,在项目中不能缺少。
    主要用来注册小程序;
  • app.json
    小程序的主配置文件,在项目中不能缺少。
    用来对小程序进行全局配置;
  • app.wxss
    小程序的主样式表文件,在项目中可以不要。
    作用同css。
    主样式表文件中设置的样式,在其他页面文件中也可以共享;

页面文件

微信小程序通常需要由多个页面组成,
每个页面由4个文件构成,
描述页面的这4个文件必须具备相同的路径和文件名
通过4种不同扩展名来区分,扩展名的含义:

  • js
    页面的逻辑文件,负责编写JS代码控制页面逻辑,
    每个页面必须有这个文件。
  • wxml
    页面的描述文件(类似html、htm),
    用来设计页面的布局,进行数据绑定等。
    每个页面必须有这个文件。
  • wxss
    页面的样式表文件,
    用来定义本页面使用到的各类样式表。
    同时页面可以使用app.wxss中定义的样式,如果页面使用的样式都在app.wxss中定义了,这个文件也可以省略。
    也可使用内联样式;
    有样式重复时,遵循层叠样式的规则;
  • json
    页面配置文件。
    如果页面没有特殊配置,可以省略该文件,只使用app.json中的配置即可。

其他文件

  • 小程序开发中,除了上述文件外,
    一般还会用到图片、音视频、通用js模块等文件,
    这些文件可放置在项目中的任何位置,在调用时指定相对目录即可。

  • 图片、音视频等资源类的文件也可以单独创建子目录存放。
    大文件放在后端即可。

配置文件详解

主配置文件app.json

主配置文件app.json位于项目主目录中,用来对项目进行全局配置,
对所有页面都适用;
包括配置每个页面文件的路径、窗口表现、设置网络超时时间、设置多tab等。

  • 看一下初始项目的主配置文件:
    • 配置文件的内容 即 一个JSON对象;

    • 属性pages【String数组类型】:定义小程序中用到的页面;
      这里配置的是两个界面,
      “pages/index”目录下的“index”界面、“pages/logs”下的“logs”界面;

      • 在小程序中要使用到的页面 须在app.json中配置,加在pages数组中。
      • pages数组的每一个item是String,定义小程序中用到的页面;
        每一个item代表对应页面的【路径+文件名】,文件名不用加后缀,框架会自动寻找路径下.json、.js、.wxml、.wxss结尾的4个文件进行编译组合。
      • pages数组的第一项,表示小程序的初始页面;
    • 属性window:定义窗口的表现形式;

      • backgroundColor:窗口背景色,
        使用十六进制的RGB方式设置颜色,
        如#ff0000为红色,默认值为白色 #ffffff;
      • navigationBarTitleText:设置标题文本;
      • navigationBarTextStyle:导航栏标题颜色,支持black和white两个值;
      • navigationBarBackgroundColor:设置标题导航栏背景颜色;
      • backgroundTextStyle:设置下拉背景字体、loading图的样式,
        只支持dark、light两个值;
      • enablePullDownRefresh,是否开启下拉刷新,默认为false;
  • 配置窗口底部tabBar

    • app.json中加一个“tabBar”属性(数组类型),
      最少配置2个、最多5个tab;
      tab按数组的顺序排序;
      每个tab可配置显示的文字、图标等选项;
      对于整个tabBar也可以通过属性进行配置;

    • tabBar有5个属性:

      • color,设置tab 未激活状态的 文字颜色;
      • selectedColor,设置tab 激活状态的 文字颜色;
      • borderStyle,设置tabBar上边框的颜色,支持“black”或“white”;
      • backgroundColor,设置tab的背景色,如#ffffff;
      • list,数组,设置tab的列表项,最少2个、最多5个;
    • list 数组的每一项是一个JSON对象,可以设置4个属性值:

      • text,tab上显示的文字;
      • iconPath,
        设置tab 处于 未激活状态时 显示的图片路径,icon图片大小限制为40KB;
      • selectedIconPath,设置tab 处于 激活状态时 显示的图片路径,
      • pagePath,设置点击tab时 跳转的页面路径;
        注意这里的路径必须在pages中配置过。
  • 网络配置
    networkTimeout属性【JSON对象类型】,
    可以设置 各种 网络请求的超时时间【单位:ms】;

    • connectSocket,设置wx.connectSocket 接口网络请求 的 超时时间;
    • downloadFile,设置wx.downloadFile 下载文件接口 的 超时时间;
    • uploadFile,设置wx.uploadFile 上传文件接口 的 超时时间;
    • request,设置wx.request网络请求接口 的 超时时间;
  • debug属性
    可以在开发者工具中开启 debug模式,
    在开发者工具的 控制台面板,调试信息info的形式给出,
    其信息有Page的注册、页面路由、数据更新和事件触发
    可以快速定位一些常见的问题;

例程:

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"dark",
    "navigationBarBackgroundColor": "#0af",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"white"
  },
  "tabBar":{
    "color":"#dddddd",
    "selectedColor":"#3cc51f",
    "borderStyle":"black",
    "backgroundColor":"#ffffff",
    "list":[{
      "pagePath": "pages/index/index",
      "text":"首页"
    },{
      "pagePath": "pages/logs/logs",
      "text":"日志"
    }]
  },
  "networkTimeout":{
    "request":10000,
    "downloadFile":10000
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

页面配置文件

  • 页面配置文件的文件名 与 页面其他3个文件名相同,扩展名为.json;
    如index页面的配置文件名全称为 index.json;
  • 页面配置 比 主配置文件要 简单,
    因为在页面配置文件中,
    只能设置 app.json 中的 window配置项的内容(页面配置 会覆盖 主配置 的相同的属性内容),
    最终决定本页面的窗口表现
    无需写window这个键,但要保留花括号;
    例程:
{
  "navigationBarBackgroundColor":"#00aaff",
  "navigationBarTextStyle":"black",
  "navigationBarTitleText": "查看启动日志(Demo)",
  "backgroundColor":"#eeeeee",
  "backgroundTextStyle":"dark",
  "usingComponents": {}
}

逻辑层js文件

小程序作为前端:

  • 通常要对 从后端接收到数据进行进一步的加工;

  • 界面中的数据也可能会 根据数据的变化 而改变;
    这些都需要前端的逻辑代码实现;

  • 小程序分逻辑层和视图层;
    逻辑层将数据进行处理后 发送给 视图层,
    同时接受视图层的 事件反馈。

  • 官方为方便小程序开发,
    在JS的基础上做了封装和修改:

    • 提供了App 和 Page 方法,用来进行程序和页面的注册;

    • 提供丰富的API,如扫一扫、支付 等微信特有能力;

    • 每个页面有 独立的作用域, 并提供模块化能力;

    • 由于框架没有运行在浏览器中,
      所以JS在Web中的一些能力无法使用,
      如不能方法document、window等JS对象;

    • 开发者写的所有代码 最终将被打包成一份JS,
      并在小程序启动的时候运行,直到小程序销毁。
      类似ServiceWorker,所以逻辑层也称之为App Service

用App函数注册小程序

  • 每个微信小程序必须在app.js中进行程序的注册,并且只能注册一次;
    因此,主逻辑文件app.js中必须包含注册的方法;
  • 注册小程序直接使用App()函数即可,
    函数参数是一个JSON对象
    在这个对象中可指定小程序的生命周期函数
    • onLaunch:当小程序初始化完成时,会触发onLaunch,全局只触发一次;
    • onShow:当小程序启动,或从后台进入前台显示,会触发onShow
    • onHide:当小程序从前台进入后台,会触发onHide
      如点击关闭按钮,或手机的返回主界面按钮离开微信时,
      小程序并不会直接被销毁,只是进入了后台,触发onHide
      (前后后台 指 小程序界面 是否展示出来)
  • 当小程序 进入后台一定时间,或手机资源占用过高,就会被 手机系统 从后台销毁
  • 看下初始项目的主逻辑文件【app.js】:
//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})
  • 上述代码中,
    只定义了onLaunch函数,没定义onShow、onHide函数,
    这3个函数其实都不是必须的,按需定义即可;

  • 开发者可以在App()函数中 添加 任意名称的函数数据参数中,以完成特定的功能

用Page函数注册页面

  • 小程序中每个页面 必须使用 Page() 函数进行注册,
    函数参数 类似App()注册程序函数,是一个JSON对象
    在这个对象中可定义页面的生命周期函数
    也可编写 自定义的函数响应页面的事件

  • 在参数中 有一个 data属性,用于定义页面中使用到的数据;

  • 页面逻辑文件的文件名 与 页面其他3个文件名相同,扩展名为.js;
    如index页面的配置文件名全称为 index.js;

  • 看下初始项目的index.js:

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    motto: 'Hello World',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  }
})
  • 初始化数据

    • 初始化数据位于data中,初始化数据 将作为页面的第一次渲染;
    • data将会以JSON的形式 由 逻辑层 传至 视图层
      所以其 数据 必须是可以转成 JSON格式的数据
      字符串、数字、布尔值、对象、数组等;

      如上,
      在data中定义了motto【字符串】,
      定义了userInfo【空对象】;
    • 视图层 可以 通过wxmldata中定义的数据 进行绑定;
  • 生命周期函数

    • Page()函数的参数中,可定义当前界面生命周期函数








参考自《从零开始学微信小程序开发》

推荐阅读更多精彩内容