事件系统
事件为页面/组件等实例内部封装逻辑与自定义逻辑的交互方式。当触发事件时逻辑层根据事件绑定的响应,执行对应的处理函数。
微搭中事件流是一组通过各种规则串联动作的集合。事件流分两种:事件内联事件流和独立事件流。
- 内联事件流:内联在组件或页面等事件内的事件流,由绑定的事件触发,不可复用,没有独立引用。
- 独立事件流:独立定义事件流,可复用,默认通过类似实例
$w.eventflow1
来引用,需要主动触发$w.eventflow1.trigger()
事件对象 event
在处理函数的上下文中,特殊的有 event 对象用于访问当前事件的相关信息,event.detail
为当前事件携带的数据,不同事件各不相同。
event
属性 | 说明 |
---|---|
detail | 事件携带的额外数据,由触发事件时决定,不同事件各不相同 |
事件调度逻辑
事件处理除了绑定单个处理函数外,还可实现简单的流程调度。例如如下配置:
{
"listeners": [
{
"id": "wgdu718n1n8",
"eventName": "tap",
"type": "platform",
"handler": {
"name": "showLoading",
"module": "platform",
"params": {}
}
},
{
"id": "wop5v6q51hg",
"eventName": "wgdu718n1n8.success",
"type": "platform",
"handler": {
"name": "navigateTo",
"module": "platform",
"params": {
"mode": "weDa",
"packageName": "",
"pageId": "u43or8cdj0g",
"params": {}
}
}
},
{
"id": "wecc06m9th8",
"eventName": "wop5v6q51hg.success",
"type": "rematch",
"handler": {
"name": "delay",
"module": "index",
"params": {}
}
},
{
"id": "wf23d9rgp7g",
"eventName": "wecc06m9th8.success",
"type": "platform",
"handler": {
"name": "showModal",
"module": "platform",
"params": {
"cancelColor": "#000000",
"cancelText": "取消",
"confirmColor": "#576B95",
"confirmText": "确认",
"content": "请输入弹窗内容",
"showCancel": true,
"title": "弹窗标题"
}
}
}
]
}
- 同个事件上可以绑定多个不同的处理函数,这些处理函数在事件触发时被按顺序,并发调用,同事件多个处理函数之间不互相阻塞。
- 当某个事件(上述 tap 事件为例)绑定处理函数(id 为 wgdu718n1n8 的 showLoading)被触发后,会根据当前函数执行成功与否,分别触发
wgdu718n1n8.success
和wgdu718n1n8.fail
事件,成功时事件event.detail
为处理函数(showLoading)返回值,失败时为 error 对象。通过每个事件的成功失败分叉和链式串行调用来完成流程调度。 - 由于调用链中可能存在异步方法,在调用执行过程中页面生命周期状态可能发生变化,当前页面不在处于激活态(例如:页面发生跳转),此时调用链会在处理完当前任务后发生中断,即每个事件处理节点再进入时都会校验当前页面是否激活,若非激活态则直接不再执行,并不会触发后续的成功/失败事件。
事件处理 handler
事件处理节点中可以定义处理方法,自定义处理方法 (handler) 完全由开发者定义,自定义 handler 方法在适当的定义了入参和返回值后也能够完成事件流的传递。
典型的 handler 处理函数的第一个入参会有 event
和 data
两个参数,其中 event.detail
事件数据或者上一个处理节点的返回值或异常,data.target
为事件面板中的配置的入参。当 handler 函数正常通过返回内容时,成功分支的下个节点会被触发,而当 handler 函数抛出异常时,失败分支的下个节点会被触发。
比如,假设事件流中存在 function1/successHandler/failHandler
三个自定义方法的动作节点,调用关系为 function
成功时执行 successHandler
,失败时执行 failHandler
,代码如下:
export default async function ({ event, data }) {
const result = await fetch("http://example.com/movies.json").then(
(response) => response.json()
);
if (result.code) {
// 接口返回错误时抛出异常
throw new Error(result.message);
// return Promise.reject(result); // Promise.reject 也会走到异常分支
} else {
// 正常返回
return result;
}
}
假设 successHandler
绑定了额外的入参 params
,则 event.detail
为前一节点 function1
的返回值,data.target
为额外入参 params
export async default function ({ event, data }) {
const result = event.detail; // event.detail 指向上一节点的返回值
const params = data.target; // data.target 指向动作节点额外入参
console.log('done', result, params);
// ... 成功处理过程
}
当 function1
异常时,failHandler
中 event.detail
为 function1
的异常信息。
export async default function ({ event, data }) {
const error = event.detail; // event.detail 指向上一节点的错误信息
const params = data.target; // data.target 指向动作节点额外入参
console.log('fail', error, params);
// ... 失败处理过程
}
阻止事件冒泡
当事件为冒泡事件时(如:点击-tap),可以在下图位置设置阻止事件冒泡