wx-mini-weview
Version:
weixin UI
162 lines (135 loc) • 4.77 kB
JavaScript
/**
* 组件事件行为
* 扩展组件的事件处理能力,提供更灵活的事件监听和触发机制
*/
const WvComponentEvent = Behavior({
data: {
// 内部事件存储
_wvEventListeners: {}
},
lifetimes: {
attached() {
// 保存原始 triggerEvent 方法引用
this._originalTriggerEvent = this.triggerEvent;
// 重写 triggerEvent 方法
this.triggerEvent = (eventName, detail, options) => {
// 调用原始方法
const result = this._originalTriggerEvent.call(this, eventName, detail, options);
// 同时触发我们的自定义事件系统
this.emit(eventName, detail);
return result;
};
},
detached() {
// 清理所有事件监听,避免内存泄漏
this.clearAllListeners();
// 恢复原始 triggerEvent 方法
if (this._originalTriggerEvent) {
this.triggerEvent = this._originalTriggerEvent;
this._originalTriggerEvent = null;
}
}
},
methods: {
/**
* 注册事件监听器
* @param {String} eventName - 事件名称
* @param {Function} callback - 回调函数
* @param {String} [scope] - 可选的作用域标识,用于分组和选择性移除
* @return {Object} 组件实例,用于链式调用
*/
on(eventName, callback, scope = 'default') {
if (typeof callback !== 'function') {
console.warn('[WvComponentEvent] 注册的回调必须是函数');
return this;
}
// 初始化事件存储结构
if (!this.data._wvEventListeners[eventName]) {
this.data._wvEventListeners[eventName] = {};
}
if (!this.data._wvEventListeners[eventName][scope]) {
this.data._wvEventListeners[eventName][scope] = [];
}
// 添加监听器
this.data._wvEventListeners[eventName][scope].push(callback);
return this;
},
/**
* 移除事件监听器
* @param {String} eventName - 事件名称
* @param {String} [scope] - 可选的作用域标识,如果不提供则移除该事件的所有监听器
* @return {Object} 组件实例,用于链式调用
*/
off(eventName, scope) {
if (!this.data._wvEventListeners[eventName]) {
return this;
}
if (scope === undefined) {
// 移除该事件的所有监听器
delete this.data._wvEventListeners[eventName];
} else if (this.data._wvEventListeners[eventName][scope]) {
// 移除指定作用域的监听器
delete this.data._wvEventListeners[eventName][scope];
}
return this;
},
/**
* 触发事件
* @param {String} eventName - 事件名称
* @param {...*} args - 传递给监听器的参数
* @return {Object} 组件实例,用于链式调用
*/
emit(eventName) {
if (!this.data._wvEventListeners[eventName]) {
return this;
}
// 获取除了eventName之外的所有参数
var args = Array.prototype.slice.call(arguments, 1);
var self = this;
// 立即触发,不使用setTimeout
var eventListeners = this.data._wvEventListeners[eventName];
var scopes = Object.keys(eventListeners);
for (var i = 0; i < scopes.length; i++) {
var scope = scopes[i];
var listeners = eventListeners[scope];
if (!listeners) continue;
for (var j = 0; j < listeners.length; j++) {
try {
listeners[j].apply(self, args);
} catch (error) {
console.error('[WvComponentEvent] 执行事件"' + eventName + '"的监听器出错:', error);
}
}
}
return this;
},
/**
* 清理所有事件监听器
* @return {Object} 组件实例,用于链式调用
*/
clearAllListeners() {
this.data._wvEventListeners = {};
return this;
},
/**
* 检查是否有指定事件的监听器
* @param {String} eventName - 事件名称
* @return {Boolean} 是否有监听器
*/
hasListeners(eventName) {
return !!this.data._wvEventListeners[eventName] &&
Object.keys(this.data._wvEventListeners[eventName]).length > 0;
},
/**
* 获取指定事件的所有监听器
* @param {String} eventName - 事件名称
* @return {Object} 按作用域分组的监听器
*/
getListeners(eventName) {
return this.data._wvEventListeners[eventName] || {};
}
}
});
module.exports = {
WvComponentEvent
};