小程序开发基础
介绍小程序开发的基础知识
小程序的生命周期
小程序的生命周期分组件生命周期和页面生命周期
小程序的架构
- 使用纯客户端的原生技术来编码渲染,就意味着小程序要与微信本身的代码一起编译打包和发布版本,那么小程序的开发节奏就无法做到像 Web 那样快;
- 如果我们使用纯 Web 的技术来做页面渲染,那么页面的渲染和页面逻辑执行的脚本就会处于同一个线程,容易导致业务逻辑和 UI 渲染互相抢占资源,从而在一些较为复杂的页面上出现一些性能问题;
- 如果采用介于客户端原生技术与 Web 技术之间的渲染方式,小程序使用混合模式开发,就可以像 Web 一样支持在线快速更新,又可以跨平台,同时比 Web 更接近原生体验,保持原生 App 良好的用户交互体验优势。
逻辑层
逻辑层主要进行数据请求和业务逻辑处理,通过 JS 引擎提供的沙箱环境来执行JS。与浏览器 Web 开发相比,逻辑层开发无法直接操作 DOM 和 BOM,无法使用一些浏览器暴露的接口(如跳转页面、动态执行脚本),从而提高了管控力和安全性。逻辑层主要负责将数据进行处理后再发送给渲染层,同时接收渲染层的事件反馈,对数据进行反向操作。对微信小程序来说,逻辑层就是所有 js 文件的集合。
渲染层
渲染层主要在 WebView 线程中执行界面渲染相关的任务,对于微信小程序而言,渲染层就是所有 WXML(WeiXin Mark Language)文件与 WXSS(WeiXin Style Sheet)文件的集合。通过 Virtual DOM 减少渲染开销,提高局部更新数据和重渲染的效率,让页面更流畅。
系统层
- 通过 JSBridge 构建 JS 和 Native 之间的通信,以便上层间接调用客户端的原生底层接口;
- 通过 JSBridge 构建 JS 和 Native 之间的通信,以便上层间接调用客户端的原生底层接口;
- 通过 JSBridge 构建 JS 和 Native 之间的通信,以便上层间接调用客户端的原生底层接口;
在双线程模型下,把界面渲染和逻辑处理分离、并行处理,可以加快渲染速度,避免单线程模型下因为 JS 运算时间过长导致的 UI 卡顿问题。并且,采用数据驱动的方式,开发者将无法直接操作 DOM,可以加强管控和安全。但是,双线程模型也意味着逻辑层与渲染层之间的通信、各层与客户端的原生交互会有一定的延时。
小程序的开发框架
小程序开发使用的框架称为 MINA 框架,包含上面提到的逻辑渲染系统三层
小程序的逻辑层开发
文件结构
主体文件
小程序的主体文件是全局文件,必须放在项目的根目录,它的配置会影响整个小程序项目。小程序的主体文件主要由 3 个文件组成
页面文件
- index.wxml 作为页面结构描述,负责页面渲染;
- index.json 作为页面配置,可以覆盖上述主体文件中 app.json 的配置;
- index.wxss 是针对 index.wxml 的样式补充;
- index.js 用来作为业务逻辑处理 在项目目录中,js、app.json、wxml、wxss 文件会经过编译,因此上传之后无法直接访问,其中 wxml 和 wxss 文件仅针对在 app.json 中配置了的页面。除此之外,只有后缀名在白名单内的文件可以被上传,不在白名单内的文件可以在开发工具内访问,但无法被上传
小程序的配置
对于初学者来说,只需要记住 3 个核心配置项的内容即可:页面路由配置项、窗口表现配置项和底部标签导航配置项。
页面路由配置项
"pages": [
"pages/index/index",
"pages/demo/demo",
"pages/center/center",
"pages/modifyaddr/modifyaddr",
"pages/address/address",
"pages/cart/cart",
"pages/productlist/productlist",
"pages/detail/detail",
"pages/noticedetail/noticedetail",
"pages/class/class",
"pages/help/help"
]
实际执行时是按照字母序(文件排序方式)加载的。当然,默认的第一个页面会设定为小程序的首页。
小技巧:我们如果要新创建一个页面访问路径,只需要在配置文件中加上这个页面路径的地址,小程序开发工具就会自动生成对应的文件夹及文件夹下对应的 js、json、wxml、wxss 基本文件。
窗口表现配置项
窗口展示配置包括:
- 导航栏背景颜色配置(navigationBarBackgroundColor)
- 导航栏标题颜色配置(navigationBarTextStyle)
- 导航栏标题文字内容配置(navigationBarTitleText)
- 导航栏样式配置(navigationStyle)
- 等;
窗口效果配置
主要包含:
- 是否开启全局的下拉刷新(enablePullDownRefresh)
- 屏幕旋转方向设置(pageOrientation)
- 等 该配置项的内容基本是可选的。对大部分开发者来说,只需要完成配置navigationBarTitleText 即可,这个配置标注了小程序默认的导航栏标题文字内容。
底部标签导航配置项
tabBar属性
color 属性是指 tab 上的文字默认颜色,仅支持十六进制颜色;selectedColor 属性是指 tab 上的文字选中时的颜色;backgroundColor 指出了 tab 的背景色;list 属性是 tab 的列表数组,它只能配置最少 2 个、最多 5 个 tab list 配置项是这个配置中的核心,它是一个数组,tab 按数组的顺序排序,每个项都是一个对象,每个对象包含 pagePath、text 两个必填项和 iconPath、selectedIconPath 两个选填项。后面两个配置项是 tabBar 支持配置图片icon。
"tabBar": {
"color": "#7c7c7c",
"selectedColor": "#f7545f",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/tabbar/home.png",
"selectedIconPath": "images/tabbar/curhome.png",
"text": "首页"
},
{
"pagePath": "pages/class/class",
"iconPath": "images/tabbar/class.png",
"selectedIconPath": "images/tabbar/curclass.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "images/tabbar/cart.png",
"selectedIconPath": "images/tabbar/curcart.png",
"text": "购物车"
},
{
"pagePath": "pages/center/center",
"iconPath": "images/tabbar/person.png",
"selectedIconPath": "images/tabbar/curperson.png",
"text": "个人"
}
]
},
页面配置文件解析
除了全局配置文件外,每一个小程序页面也可以使用同名 json 文件来对本页面的窗口表现进行配置,页面配置文件只能设置全局配置文件中 window 相关的配置项,也就是可以指定各个页面的窗口表现,页面配置文件中的配置项会覆盖 app.json 的 window 中相同的配置项。
小程序的场景值
场景值用来描述用户进入小程序的路径,可以帮助开发者了解用户是如何访问我们的小程序的
App({
onLaunch: function(options) {
console.log("[onLaunch] 场景值:", options.scene)
},
onShow: function(options) {
console.log("[onShow] 场景值:", options.scene)
}
})
页面注册与生命周期
微信小程序是通过 app.js 来管理生命周期的
应用生命周期的注册
一般使用 App(Object object) 来注册小程序,从而管理自己的生命周期。每个小程序都需要在 app.js 中调用 App() 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。在 app.js 中,这个函数接收一个Object 参数,其中指定了小程序的生命周期回调 App() 必须在 app.js 中注册。在一个小程序中,App() 方法有且仅有一个,不能注册多个,否则可能会出现无法预期的后果 app.js 除了定义生命周期外,还可定义全局变量,通过 **getApp()**获取app实例
// other.js
var appInstance = getApp()
console.log(appInstance.globalData)
注意:
- App() 必须在 app.js 中注册,不可以在 App() 函数内或在定义 App() 函数前调用 getApp() 方法;
- 通过 getApp() 方法获取实例后,不可以私自调用生命周期函数
页面生命周期的注册
// pages/index/hello.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
Page 这个 prototype 中还注册了 data 属性、route 属性和 setData()方法。 Page.prototype.route() 方法可以获取当前所处的页面,也可以使用 getCurrentPages() 函数获取当前页面栈,该函数用于获取当前页面栈的实例,并以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。而 Page.prototype.data 就是当前页面的数据内容。 小程序的每个页面都有一个 data 对象来存放当前页面的数据,可以使用Page.prototype.setData() 来修改
渲染页面
- 如何渲染页面
- 你在代码中写的初始化 data 数据将传递给渲染层进行第一次渲染。data 会以JSON 的形式由逻辑层传至渲染层,所以数据必须可以转成 JSON 的格式:字符串、数字、布尔值、对象、数组。