现如今mvvm框架如此火热,其核心思想即js逻辑层不直接操作DOM,只改变组件状态;而视图层则通过模板template进行渲染。
1.WePy项目的目录结构
├── dist 小程序运行代码目录 ├── node_modules 依赖 ├── src 代码编写的目录 | ├── components WePY组件目录 | | ├─- com_a.wpy 可复用的WePY组件a | | └── com_b.wpy 可复用的WePY组件b | ├── pages WePY页面目录(属于完整页面) | | ├── index.wpy index页面 | | └── other.wpy other页面 | └── app.wpy 小程序配置项(全局数据、样式、声明钩子等) └── package.json 项目的package配置
二、实例
小程序定义了三大实例类,App、Page、Component;
2.1 App
入口文件app.wpy声明的小程序实例继承至wepy.app类,包含小程序的生命周期函数、config配置、全局属性方法及自定义方法。
export default class extends wepy.app { config = { pages: [ //页面配置 'pages/index/index', 'pages/personals/personal', ], window: { backgroundTextStyle: 'light', navigationBarBackgroundColor: '#a22b00', navigationBarTitleText: '', navigationBarTextStyle: 'white' }, tabBar: { //tab栏 list: [ { pagePath: 'pages/index/index', text: '首页', iconPath: './static/images/icon-index2.png', selectedIconPath: './static/images/icon-index1.png' }, { pagePath: 'pages/personals/personal', text: '我的', iconPath: './static/images/icon-my2.png', selectedIconPath: './static/images/icon-my1.png' } ], color: '#000', borderStyle: 'white', selectedColor: '#ff5000', backgroundColor: '#ffffff' } }; globalData = { //全局数据 }; onLaunch() { //生命周期函数--监听小程序初始化(全局只触发一次) }; onShow() { //生命周期函数--监听小程序显示 }; customFunction() { //自定义方法 }; }
2.2 Page
page页面继承至wepy.page类,该类主要属性如下:
- config 页面配置对象,对应于原生的
page.json
文件; -
components 页面组件列表对象;
- data 页面渲染数据对象,存放可用于页面模板绑定的渲染数据;
-
methods wxml模板中事件处理函数;
- events WePy组件之间通信的函数,响应
$broadcast
、$emit
、$invoke;
- 生命周期函数 onLoad、onShow;
- 自定义方法
2.3 component
components中的组件实例继承wepy.component,本质上page也是component,所以component组件实例除了不需要config
配置以及页面特有的一些生命周期函数之外,其属性与页面属性大致相同。
三、组件间的通信
wepy.component
基类提供$broadcast
、$emit
、$invoke
三个方法用于组件之间的通信和交互。
this.$emit(funName,arg1,arg2);
组件间通信的事件处理函数需要写在组件和页面的events对象中,但是$invoke触发的事件在methods中响应:
import wepy from 'wepy' export default class Com extends wepy.component { components = {}; data = {}; methods = { //响应$invoke funNamet: (p1, p2, $event) => { //处理逻辑 } }; // events对象中所声明的函数为用于监听组件之间的通信与交互事件的事件处理函数 events = { //响应$emit、$broadcast funNamet: (p1, p2, $event) => { //处理逻辑 } }; // Other properties }
$broadcast
事件是由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消,捕获顺序。
$emit
与$broadcast
正好相反,事件发起组件的所有祖先组件会依次接收到$emit
事件,冒泡顺序。
$invoke
是一个页面或组件对另一个组件中的方法的直接调用,通过传入组件路径找到相应的组件,然后再调用其方法。
四、数据绑定
原生小程序的数据绑定方式
原生小程序通过Page
提供的setData
方法来绑定数据,如:
this.setData({title: 'this is title'});
WePY数据绑定方式
Wepy使用脏数据检查对setData进行封装,在函数执行周期结束时进行脏数据检查。一来不用关心页面多次setData是否有性能上的问题;二来可以更加简洁去修改数据实现绑定。
this.title = 'this is title';
值得注意的是,在异步绑定数据时,需要执行$apply()才会触发脏数据检查,
setTimeout(() => { this.title = 'this is title'; this.$apply(); }, 3000);
WePY脏数据检查流程
在执行脏数据检查时,会通过this.$$phase
标识当前检查状态,并且会保证在并发的流程当中,只会有一个脏数据检查流程在运行,以下是执行脏数据检查的流程图: