UNPKG

wx-mini-weview

Version:

weixin UI

162 lines (135 loc) 4.77 kB
/** * 组件事件行为 * 扩展组件的事件处理能力,提供更灵活的事件监听和触发机制 */ 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 };