框架结构
一般软件的应用架构:- 微信小程序是一套系统的展示层;
小程序项目目录结构
wxml 类比 html 页面描述文件
js 页面逻辑文件
wxss 类比 css 样式表文件主目录中,
3个app开头的文件就是微信小程序框架的主描述文件,
这3个文件不属于任何页面;-
pages目录下还有2个子目录——index、logs:
分别是页面中的逻辑文件、页面结构文件、样式表文件、配置文件;
为了减少开发时的配置项,框架特别约定描述页面的这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;
- backgroundColor:窗口背景色,
-
配置窗口底部
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【空对象】; - 视图层 可以 通过
wxml
对data中定义的数据
进行绑定;
- 初始化数据位于
-
生命周期函数
- 在
Page()函数
的参数中,可定义当前界面
的生命周期函数
- 在
参考自《从零开始学微信小程序开发》