简介
VTable 内部的事件监听了两种类型的事件,分别是原生 DOM 事件、内置自定义事件。
本文将讲解自定义事件的定义,以及 VTable 中自定义事件相关事项。
自定义事件
在前端开发中,Javascript 和 HTML 之间都是通过事件来进行通信,像是失焦、点击、鼠标移动等。事件是一种通信方式,我们可以通过监听事件来完成页面的交互功能。
但是对于复杂的项目,基础事件无法满足业务需求,这时就可以引入自定义事件了**。**
常规的事件采用的是观察者模式,他的触发时机是在用户进行相应操作后进行触发,而自定义事件采用的是发布-订阅的模式 ,允许开发者自行决定注册与触发时机。
自定义事件需要先进行注册,如下图所示,在E模块中先进行注册和传入对应的回调,随后便可以在其他模块中触发自定义事件,执行对应的回调。

在 VTable 中,自定义模块最主要是用于下面这条链路,当用户进行交互的时候,触发对应的自定义事件,更改状态模块,触发表格组件重新渲染,实现 VTable 中的交互系统。

自定义事件除了用来在各个不同模块之间进行通信以外,还能用来让业务方注册自定义事件,实现自定义逻辑。

内置事件分类
在 VTable 内部,提供了高达 50 多种内置事件,下面根据不同的分类来介绍:
-
单元格相关
-
CLICK_CELL 鼠标点击单元格事件
-
DBLCLICK_CELL 鼠标双击单元格事件
-
SELECTED_CELL 单元格选中状态改变事件
-
SELECTED_CLEAR 单元格选中状态改变事件
-
DRAG_SELECT_END 拖拽框选单元格鼠标松开事件
-
MOUSEDOWN_CELL 单元格上鼠标按下事件
-
MOUSEUP_CELL 单元格鼠标松开事件
-
MOUSEMOVE_CELL 鼠标在某个单元格上移动事件
-
MOUSEENTER_CELL 鼠标进入单元格事件
-
MOUSELEAVE_CELL 鼠标离开单元格事件
-
CHANGE_CELL_VALUE 更改单元格值的事件
-
COPY_DATA 单元格内容复制事件
-
CONTEXTMENU_CELL 单元格右键事件
-
CONTEXTMENU_CANVAS 画布右键事件
-
键盘相关事件
-
KEYDOWN 键盘按下事件
-
表格相关事件
-
MOUSEENTER_TABLE 鼠标进入表格事件
-
MOUSELEAVE_TABLE 鼠标离开表格事件
-
MOUSEDOWN_TABLE 鼠标点击表格事件
-
MOUSEMOVE_TABLE 鼠标在表格上移动事件
-
行高列宽调整事件
-
RESIZE_COLUMN 列宽调整事件
-
RESIZE_COLUMN_END 列宽调整结束事件
-
RESIZE_ROW 行高调整事件
-
RESIZE_ROW_END 行高调整结束事件
-
拖拽表头移动位置的事件
-
CHANGE_HEADER_POSITION_START 拖拽表头或者拖拽行来移动位置开始事件
-
CHANGE_HEADER_POSITION 拖拽表头或者行来移动位置的事件
-
CHANGING_HEADER_POSITION 拖拽表头或者拖拽行移动过程事件
-
CHANGE_HEADER_POSITION_FAIL 拖拽表头或者行来移动位置的失败事件
-
排序相关事件
-
SORT_CLICK *点击排序图标事件。*ListTable 专有事件
-
PIVOT_SORT_CLICK *透视表中排序图标点击事件。*PivotTable 透视表专有事件
-
AFTER_SORT 执行完排序事件。ListTable 专有事件 **
-
图标事件
-
ICON_CLICK icon 图标点击事件
-
FREEZE_CLICK 点击固定列图标冻结或者解冻事件
-
DRILLMENU_CLICK *下钻按钮点击事件。*透视表专有事件
-
滚动事件
-
SCROLL 滚动表格事件
-
SCROLL_HORIZONTAL_END 横向滚动到右侧结束事件
-
SCROLL_VERTICAL_END 竖向滚动条滚动到底部事件
-
迷你图事件
-
MOUSEOVER_CHART_SYMBOL 鼠标经过迷你图标记事件
-
下拉菜单事件
-
DROPDOWN_MENU_CLICK 下拉菜单选项的点击事件
-
DROPDOWN_ICON_CLICK 点击下拉菜单按钮
-
DROPDOWN_MENU_CLEAR 清空下拉菜单事件(菜单显示时点击其他区域)
-
SHOW_MENU 显示菜单事件
-
HIDE_MENU 隐藏菜单事件
-
图例事件
-
LEGEND_ITEM_CLICK 图例项点击事件。图例专有事件 **
-
LEGEND_ITEM_HOVER 图例项 hover 事件。图例专有事件 **
-
LEGEND_ITEM_UNHOVER 图例项 hover 到 unhover 事件。图例专有事件 **
-
LEGEND_CHANGE 颜色图例,尺寸图例,用户操作图例范围后触发该事件。图例专有事件 **
-
透视图坐标轴事件
-
MOUSEENTER_AXIS 鼠标进入到坐标轴上事件。坐标轴专有事件 **
-
MOUSELEAVE_AXIS 鼠标离开坐标轴事件。坐标轴专有事件 **
-
状态更改
-
CHECKBOX_STATE_CHANGE 更改 checkbox 复选框状态。ListTable 表格专有事件 **
-
RADIO_STATE_CHANGE 更改 radio 单选框状态。ListTable 表格专有事件 **
-
TREE_HIERARCHY_STATE_CHANGE 树形结构展开收起的点击事件
-
生命周期
-
AFTER_RENDER 每次渲染完成后触发
-
INITIALIZED 成功初始化完 成后触发
-
填充柄事件
-
DRAG_FILL_HANDLE_END 拖拽填充柄结束事件
-
MOUSEDOWN_FILL_HANDLE 拖拽填充柄点击事件
-
DBLCLICK_FILL_HANDLE 拖拽填充柄双击事件
-
空数据提示
-
EMPTY_TIP_CLICK 空数据提示点击事件
-
EMPTY_TIP_DBLCLICK 空数据提示双击事件
参考文档:
自定义事件的实现
自定义事件的实现,基于EventTarget 模块。
模块内部提供了 on 方法,通过该方法可以实现自定义事件注册的功能,同时自定义事件的类型也可以交由开发者自定义。
// packages\vtable\src\event\EventTarget.ts
export class EventTarget {
private listenersData: {
listeners,
listenerData
} = {
listeners: {},
listenerData: {}
};
on(type, listener) {
const list: TableEventListener<TYPE>[] =
this.listenersData.listeners[type] || (this.listenersData.listeners[type] = []);
list.push(listener);
const id = idCount++;
this.listenersData.listenerData[id] = {
type,
listener,
remove: (): void => {
delete this.listenersData.listenerData[id];
const index = list.indexOf(listener);
list.splice(index, 1);
if (!this.listenersData.listeners[type].length) {
delete this.listenersData.listeners[type];
}
}
};
return id;
}
off(idOrType, listener): void {
//...
}
addEventListener(type, listener, option): void {
//...
}
removeEventListener(type, listener) {
//...
}
hasListeners(type) {
//...
}
fireListeners(type, event){
//...
}
release(): void {
//...
}
}
观察 on 方法,我们可以看到内部对注册的自定义事件回调做了收集,同时为每一个回调分配了唯一id,后续可通过该 id 对回调进行注销操作。
自定义事件的触发则是通过 fireListeners。
以双击自动列宽为例:
- 在
EventManager中注册DBLCLICK_CELL事件
// packages\vtable\src\event\event.ts export class EventManager { constructor() { // ... bindSelfEvent(); // ... } bindSelfEvent() { // ... this.table.on(TABLE_EVENT_TYPE.DBLCLICK_CELL, () => { // 处理双击自动列宽 }) // ... } }
- 在双击事件的回调中,触发
DBLCLICK_CELL事件,执行处理双击自动列宽的逻辑。
// packages\vtable\src\event\listener\table-group.ts eventManager.gesture.on('doubletap', e => { dblclickHandler(e, table); }); function dblclickHandler(e: FederatedPointerEvent, table: BaseTableAPI) { // ... table.fireListeners(TABLE_EVENT_TYPE.DBLCLICK_CELL, cellsEvent); //... }
事件注册时机
VTable 中大部分的内置事件注册都是在 EventManager 事件管理模块中完成的,其余少部分的内置事件是在其它组件模块中单独去注册的,包括 MenuHandler、EditManager、 TooltipHandler 等。我们来简单看下各个模块都注册了哪些事件吧。
-
EventManager
-
ICON_CLICK
-
DROPDOWN_MENU_CLICK
-
DBLCLICK_CELL
-
MOUSEMOVE_CELL
-
MOUSELEAVE_TABLE
-
...
-
MenuHandler
-
DROPDOWN_ICON_CLICK
-
DROPDOWN_MENU_CLEAR
-
CONTEXTMENU_CELL
-
CONTEXTMENU_CANVAS
-
EditManager
-
DBLCLICK_CELL
-
CLICK_CELL
-
TooltipHandler
-
MOUSEENTER_CELL
-
MOUSEMOVE_CELL
-
MOUSELEAVE_CELL
-
SELECTED_CELL
-
MOUSELEAVE_TABLE
-
SCROLL
-
...
结语
VTable 中提供了十分丰富的内置事件,通过注册这些内置事件,业务方可以完成绝大多数的自定义业务逻辑,内置事件的存在使得表格能够更具灵活性。
本文档由以下人员提供
taiiiyang(https://github.com/taiiiyang)