一、框架
小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
1.响应的数据绑定
框架的核心是一个响应的数据绑定系统,可以让数据与视图非常简单地保持同步。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。
通过这个简单的例子来看:
在开发者工具中预览效果
<!-- This is our View --> <view> Hello {{name}}! </view> <button bindtap="changeName"> Click me! </button> // This is our App Service. // This is our data. var helloData = { name: 'Weixin' } // Register a Page. Page({ data: helloData, changeName: function(e) { // sent data change to view this.setData({ name: 'MINA' }) } })
开发者通过框架将逻辑层数据中的 name 与视图层的 name 进行了绑定,所以在页面一打开的时候会显示 Hello Weixin!;
当点击按钮的时候,视图层会发送 changeName 的事件给逻辑层,逻辑层找到并执行对应的事件处理函数;
回调函数触发后,逻辑层执行 setData 的操作,将 data 中的 name 从 Weixin 变为 MINA,因为该数据和视图层已经绑定了,从而视图层会自动改变为 Hello MINA!。
2.页面管理
框架 管理了整个小程序的页面路由,可以做到页面间的无缝切换,并给以页面完整的生命周期。开发者需要做的只是将页面的数据、方法、生命周期函数注册到 框架 中,其他的一切复杂的操作都交由 框架 处理。
3.基础组件
框架 提供了一套基础的组件,这些组件自带微信风格的样式以及特殊的逻辑,开发者可以通过组合基础组件,创建出强大的微信小程序 。
4.丰富的 API
框架 提供丰富的微信原生 API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。
二、视图层 View
1.介绍
框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。
将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。
WXML(WeiXin Markup language) 用于描述页面的结构。
WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXSS(WeiXin Style Sheet) 用于描述页面的样式。
组件(Component)是视图的基本组成单元。
2.WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
要完整了解 WXML 语法,请参考WXML 语法参考。
用以下一些简单的例子来看看 WXML 具有什么能力:
<!--wxml--> <view> {{message}} </view>
// page.js Page({ data: { message: 'ar.小白' } })
2.2.列表渲染
<!--wxml--> <view wx:for="{{array}}"> {{item}} </view>
// page.js Page({ data: { array: [1, 2, 3, 4, 5] } })
2.3.条件渲染
<!--wxml--> <view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view> <view wx:elif="{{view == 'APP'}}"> APP </view> <view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js Page({ data: { view: 'MINA' } })
2.4.模板
<!--wxml--> <template name="staffName"> <view> FirstName: {{firstName}}, LastName: {{lastName}} </view> </template> <template is="staffName" data="{{...staffA}}"></template> <template is="staffName" data="{{...staffB}}"></template> <template is="staffName" data="{{...staffC}}"></template>
// page.js Page({ data: { staffA: {firstName: 'Hulk', lastName: 'Hu'}, staffB: {firstName: 'Shang', lastName: 'You'}, staffC: {firstName: 'Gideon', lastName: 'Lin'} } })
3. 小程序的生命周期
下图说明了页面 Page 实例的生命周期。
写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决。
小程序由两大线程组成:负责界面的线程(view thread)和服务线程(appservice thread),各司其职由互相配合下面我用代码的方式来给大家演示页面跳转到底会触发那些函数。
//app.json "pages":[ "pages/index/index", "pages/a/a", "pages/b/b", "pages/c/c", "pages/d/d", "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "Weixin", "navigationBarTextStyle":"black" }, "tabBar": { "list": [{ "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/a/a", "text": "A页面" },{ "pagePath": "pages/b/b", "text": "B页面" }] }
// a.wxml <text>我是一级菜单A页面</text> <button bindtap="a2b">A页面跳转B页面</button> <button bindtap="a2c">A页面跳转C页面</button> // a.js a2b:function(){ wx.switchTab ({ url:"/pages/b/b", }) }, a2c:function(){ wx.navigateTo({ url:"/pages/c/c", }) }
小程序中,生命周期主要分成了三部分:
- 应用的生命周期
- 页面的生命周期
- 组件的生命周期
应用的生命周期是什么
小程序的生命周期函数是在app.js
里面调用的,通过App(Object)
函数用来注册一个小程序,指定其小程序的生命周期回调
页面的生命周期是什么
页面生命周期函数就是当你每进入/切换到一个新的页面的时候,就会调用的生命周期函数,同样通过App(Object)
函数用来注册一个页面
组件的生命周期是什么
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发,通过Component(Object)
进行注册组件
应用的生命周期
生命周期 | 说明 |
onLaunch | 小程序初始化完成时触发,全局只触发一次 |
onShow | 小程序启动,或从后台进入前台显示时触发 |
onHide | 小程序从前台进入后台时触发 |
onError | 小程序发生脚本错误或 API 调用报错时触发 |
onPageNotFound | 小程序要打开的页面不存在时触发 |
onUnhandledRejection() | 小程序有未处理的 Promise 拒绝时触发 |
onThemeChange | 系统切换主题时触发 |
页面的生命周期
生命周期 | 说明 | 作用 |
onLoad | 生命周期回调—监听页面加载 | 发送请求获取数据 |
onShow | 生命周期回调—监听页面显示 | 请求数据 |
onReady | 生命周期回调—监听页面初次渲染完成 | 获取页面元素(少用) |
onHide | 生命周期回调—监听页面隐藏 | 终止任务,如定时器或者播放音乐 |
onUnload | 生命周期回调—监听页面卸载 | 终止任务 |
Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例):
onLoad --页面加载
onReady --页面渲染
onShow --页面显示
onHide --页面隐藏
onUnload --页面销毁
当前页面 路由后页面 触发的生命周期(按顺序)
A A Nothing happend
A B A.onHide(), B.onLoad(), B.onReady() ,B.onShow()
A B(再次打开) A.onHide(), B.onShow()
C A C.onUnload(), A.onShow()
C B C.onUnload(), B.onLoad(), B.onShow()
D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(从转发进入) A D.onUnload(), A.onLoad(), A.onShow()
D(从转发进入) B D.onUnload(), B.onLoad(), B.onShow()
🌟总结
一级不会销毁
二级层级跳到层级低的会销毁
二级层级跳到高的只会隐藏
隔代中间所有页面会被销毁
组件的生命周期
生命周期 | 说明 |
created | 生命周期回调—监听页面加载 |
attached | 生命周期回调—监听页面显示 |
ready | 生命周期回调—监听页面初次渲染完成 |
moved | 生命周期回调—监听页面隐藏 |
detached | 生命周期回调—监听页面卸载 |
error | 每当组件方法抛出错误时执行 |
注意的是:
组件实例刚刚被创建好时, created 生命周期被触发,此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data , 此时不能调用 setData
在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行
在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发