§ Fox3.0前端框架-控制流程
Fox
§ 1.前言
Fox流程控制,目的是为了规范操作流程,并通过切面加入公共的处理逻辑,减少代码的开发量。流程主要涉及两方面:
- 页面生命周期
- 提交过程
§ 2.生命周期
Fox Flow中定义的生命周期是对Vue生命周期的二次封装,在Vue的生命周期的基础之上进行了扩展。如下图所示

青色部分为常用hook函数,其它hook则绝大多数情况下不涉及
§ 2.1 代码结构
代码结构如下:
export default {
name: "example_money-item",
//数据
data:function(){
return {
}
},
//方法
methods:{
},
//Fox流程
fox_flow() {
return {
/**
* 界面渲染后,更改数据会触发钩子函数
* @param session
* @param context
*/
mounted(session, context){
context.resolve()
},
/**
* 销毁处理
*/
beforeDestroy(session) {
}
}
}
}
PS:使用Fox Flow中的生命周期hook后,原生Vue生命周期Hook就不能使用了
§ 2.2 Fox Flow hook函数说明
§ 2.2.1、beforeCreate
实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作。
§ 2.2.2、created
挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。
§ 2.2.3、beforeMount
接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。
§ 2.2.4、mounted
接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情...
§ 2.2.5、end
在postMounted后执行,也是页面加载后最后一个hook
§ 2.2.6、beforeUpdate
当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿。
§ 2.2.7、updated
当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom。
§ 2.2.8、activated
keep-alive 组件激活时调用
§ 2.2.9、deactivated
keep-alive 组件停用时调用
§ 2.2.10、beforeDestroy
当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等。
§ 2.2.11、destroyed
组件的数据绑定、监听...去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以。
每个hook函数中都带有一个session参数,这个session对象是在flow开始的时候创建,并保留到销毁。
session的数据结构
export default class FlowSession {
/**
* 数据映射
* @type {{}}
*/
data={};
}
我们可以在data中存储一些上下文信息
§ 2.3 常用hook函数说明
我们在日常开发过程中,常用hook函数:created, mounted, beforeDestroy
§ 2.3.1 created
挂载数据、绑定事件完成后执行,更改状态不会触发渲染,可以在这里做一些参数配置操作。
created参数如下:
| 参数 | 类型 | 说明 |
|---|---|---|
| session | Object | 保存Flow整个生命周期的状态 |
§ 2.3.2 mounted
dom加载完成后触发,是开发过程中最常用的hook函数了,在这里获取后台数据,对界面进行设置操作
| 参数 | 类型 | 说明 |
|---|---|---|
| session | Object | 保存Flow整个生命周期的状态 |
| context | Object | 事件链路上下文 |
mounted是在链路中执行,preMounted->mounted->postMounted,作为链路中的一个执行节点,但任务完成后,需要调用context.resovle触发下一个任务节点。另外如果需要在mounted事件中完成多个异步,则可以通过context.insert函数插入多个子任务,如下
//插入子任务1
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_1",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//插入子任务2
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_2",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//插入子任务3
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_3",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//任务0
fox.service.request({
name:"dd/task_0",
callback:(code, message, data)=>{
context.resolve()
}
})
以上任务的执行顺序是 任务0->任务1->任务2->任务3,切记insert子任务,必须在context.resolve调用之前执行
§ 2.3.3 end
页面end执行该函数,在postMounted周期后执行,用于在postMounted后
| 参数 | 类型 | 说明 |
|---|---|---|
| session | Object | 保存Flow整个生命周期的状态 |
§ 2.3.4 beforeDestroy
页面destroy执行该函数,用于数据篮子清理等
| 参数 | 类型 | 说明 |
|---|---|---|
| session | Object | 保存Flow整个生命周期的状态 |
§ 3.提交过程
Fox Flow同样提供提交流程控制,如下图

§ 3.1 代码结构
export default {
name: "example_money-item",
//数据
data:function(){
return {
}
},
//方法
methods:{
},
//Fox流程
fox_flow() {
return {
/**
* 设置检查条件
* @param context
*/
setCheckConditions(context){
//触发check函数调用(必须执行context.resolve或context.reject)
context.resolve()
},
/**
* 提交前处理
* @param context
* @param checkResult
*/
preSubmit(context, checkResult){
console.info("pre submit流程")
//触发submit函数调用(必须执行context.resolve或context.reject)
context.resolve()
},
/**
* 提交处理
* @param context
* @param args
*/
submit(context){
console.info("submit流程")
//触发post submit函数调用(必须执行context.resolve或context.reject)
context.resolve();
},
/**
* 提交后处理
* @param context
* @param params
*/
postSubmit(context){
console.info("post submit流程")
},
/**
* 最终提交处理
* @param context
* @param params
*/
endSubmit(context){
console.info("end submit流程")
},
/**
* 提交取消处理
* @param context
* @param args
*/
cancelSubmit(context, error){
console.info(JSON.stringify(error))
},
}
}}
§ 3.2 过程说明
§ 3.2.1 commit
提交流程发起,通过框架提供的内置方法this.fox_submit方法发起,如下 html:
<fox-button type="primary" size="small" round @click="onSubmit">提交</fox-button>
js:
//方法
methods:{
//提交处理
onSubmit(){
//触发submit流程
this.fox_submit()
}
},
函数fox_submit(sessionData),参数sessionData可以为空,也可以为一个json对象,该对象会合并到session的data中。
§ 3.2.2 setCheckConditions
setCheckConditions 设置UI界面检查条件,如下
/**
* 设置检查条件
* @param context
*/
setCheckConditions(context){
//触发check函数调用(必须执行context.resolve或context.reject)
context.resolve()
},
通过context.resolve(condtions)设置UI检查条件,并触发检查操作,conditions默认为空,也就是检查整个page的校验条件
§ 设置inclue条件,只检查某些组件
下面代码指定只检查v-model绑定的expression为val10,val11的组件
/**
* 设置检查条件
* @param context
*/
setCheckConditions(context){
//触发check函数调用(必须执行context.resolve或context.reject)
context.resolve({'include':['val10','val11']})
},
§ 设置exclue条件,排除检查某些组件
下面代码指定检查页面的时候,排除v-model绑定的expression为val10,val11的组件 /** * 设置检查条件 * @param context */ setCheckConditions(context){ //触发check函数调用(必须执行context.resolve或context.reject) context.resolve({'exclude':['val10','val11']}) },
§ 3.2.3 check
check UI校验方法,该方法如无特殊需求,则不需修改,如下
/**
* 检查
* @param context
* @param conditions
*/
check(context, conditions){
//触发v-verify指令设置的检查条件
this.fox_check(conditions).then((checkResult)=>{
if(checkResult.pass){
context.resolve(checkResult)
}else{
context.reject(checkResult)
}
},(error)=>{
//设置检查原因
let reason={
type:"checkFail",
cause:error,
}
context.reject(reason);
})
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,包含函数resolve,reject和session对象 |
| conditions | Object | 检查条件 |
§ 3.2.4 preSubmit
提交前,进行业务校验处理节点,如下
/**
* 提交前处理
* @param context
* @param checkResult
*/
preSubmit(context, checkResult){
context.resolve();
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,包含函数resolve,reject和session对象 |
| checkResult | Object | 检查结果 |
当提交前处理任务完成后,调用context.resolve,触发submit处理函数,在resolve方法调用前,可以通过context.insert方法,在任务链路加入子任务,如下
//插入子任务1
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_1",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//插入子任务2
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_2",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//插入子任务3
context.insert((subContext)=>{
//子任务0
fox.service.request({
name:"dd/task_3",
callback:(code, message, data)=>{
subContext.resolve()
}
})
})
//任务0
fox.service.request({
name:"dd/task_0",
callback:(code, message, data)=>{
context.resolve()
}
})
以上任务的执行顺序是 任务0->任务1->任务2->任务3,切记insert子任务,必须在context.resolve调用之前执行
§ 3.2.5 commit
系统框架提交处理函数,在这里执行公共的提交逻辑,如下
/**
* 提交处理
* @param context
* @param args
*/
commit(context, ...args){
if(args.length>0){
Reflect.apply(context.resolve, this, args)
}else{
context.resolve();
}
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,包含函数go,resolve,reject和session对象 |
| ...args | Array | 参数列表 |
该函数用于公共逻辑提交处理,如复核提交处理
§ 3.2.6 submit
提交处理函数,在这里执行正式的提交出来逻辑,如下
/**
* 提交处理
* @param context
* @param args
*/
submit(context, ...args){
context.resolve();
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,包含函数resolve,reject和session对象 |
| ...args | Array | preSubmit函数中context.resolve(args)的参数 |
当提交前处理任务完成后,调用context.resolve,触发submit处理函数,在resolve方法调用前,可以通过context.insert方法,在任务链路加入子任务
§ 3.2.7 postSubmit
提交后处理函数,如下
/**
* 提交后处理
* @param context
* @param params
*/
postSubmit(context, ...args){
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,只有session对象 |
| ...args | Array | preSubmit函数中context.resolve(args)的参数 |
§ 3.2.8 endSubmit
提交后处理函数,如下
/**
* 最终提交处理
* @param context
* @param params
*/
endSubmit(context, ...args){
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,只有session对象 |
| ...args | Array | postSubmit函数中context.resolve(args)的参数 |
§ 3.2.9 cancelSubmit
取消后处理函数,如下
/**
* 取消后处理
* @param context
* @param params
*/
cancelSubmit(context, ...args){
}
| 参数 | 类型 | 说明 |
|---|---|---|
| conetxt | Object | 事件链路上下文,只有session对象 |
| ...args | Array | preSubmit函数中context.resolve(args)的参数 |
在上面提交流程的任何步骤(postSumbit除外),调用context.reject函数,则中断流程,直接跳转到cancelSubmit函数中