CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-dcloudio--uni-mp-qq

QQ mini-program compiler and runtime adapter for the uni-app framework that enables developers to write cross-platform applications using Vue.js syntax

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

event-channels.mddocs/

Event Channel System

Advanced event communication system for inter-page and inter-component messaging with caching, lifecycle management, and navigation integration.

Capabilities

EventChannel Class

Core class for creating isolated event communication channels between pages and components.

/**
 * Event channel for isolated communication between pages/components
 * @param id - Unique channel identifier
 * @param events - Initial event listeners (optional)
 */
class EventChannel {
  constructor(id: number, events?: Record<string, Function>);
  
  /**
   * Emit event to all listeners
   * @param eventName - Name of the event to emit
   * @param args - Arguments to pass to event listeners
   */
  emit(eventName: string, ...args: any[]): void;
  
  /**
   * Register persistent event listener
   * @param eventName - Name of the event to listen for
   * @param fn - Event handler function
   */
  on(eventName: string, fn: Function): void;
  
  /**
   * Register one-time event listener
   * @param eventName - Name of the event to listen for
   * @param fn - Event handler function (automatically removed after first call)
   */
  once(eventName: string, fn: Function): void;
  
  /**
   * Remove event listener(s)
   * @param eventName - Name of the event
   * @param fn - Specific handler to remove (optional, removes all if not provided)
   */
  off(eventName: string, fn?: Function): void;
}

Usage Examples:

// Create event channel with initial events
const eventChannel = new EventChannel(1, {
  dataUpdate: (data) => {
    console.log('Initial data update handler:', data);
  },
  statusChange: (status) => {
    console.log('Status changed to:', status);
  }
});

// Register additional event listeners
eventChannel.on('userAction', (action, userId) => {
  console.log(`User ${userId} performed action: ${action}`);
  updateUserActivity(userId, action);
});

// Register one-time listener
eventChannel.once('initialization', () => {
  console.log('Channel initialized - this runs only once');
  performInitialSetup();
});

// Emit events
eventChannel.emit('userAction', 'login', 12345);
eventChannel.emit('dataUpdate', { timestamp: Date.now(), data: {...} });
eventChannel.emit('statusChange', 'active');

// Remove specific listener
const specificHandler = (data) => console.log('Specific handler:', data);
eventChannel.on('dataUpdate', specificHandler);
eventChannel.off('dataUpdate', specificHandler); // Remove only this handler

// Remove all listeners for an event
eventChannel.off('userAction'); // Removes all userAction listeners

Channel Management Functions

Functions for creating, managing, and retrieving event channels.

/**
 * Create and initialize a new event channel
 * @param events - Initial event listeners (optional)
 * @param cache - Whether to cache the channel for later retrieval (default: true)
 * @returns EventChannel instance
 */
function initEventChannel(events?: Record<string, Function>, cache?: boolean): EventChannel;

/**
 * Retrieve and consume a cached event channel
 * @param id - Channel ID to retrieve (optional, returns next available if not provided)
 * @returns EventChannel instance or undefined
 */
function getEventChannel(id?: number): EventChannel | undefined;

Usage Examples:

import { initEventChannel, getEventChannel } from "@dcloudio/uni-mp-qq";

// Create cached event channel
const channel1 = initEventChannel({
  dataReady: (data) => {
    console.log('Data is ready:', data);
  }
}, true); // cache = true (default)

// Create non-cached event channel
const channel2 = initEventChannel({
  tempEvent: (info) => {
    console.log('Temporary event:', info);
  }
}, false); // cache = false

// Retrieve cached channel by ID
const retrievedChannel = getEventChannel(channel1.id);
console.log('Retrieved channel:', retrievedChannel === channel1); // true

// Retrieve next available cached channel (FIFO)
const nextChannel = getEventChannel(); // Returns first available cached channel

// Note: getEventChannel removes the channel from cache after retrieval
const sameChannel = getEventChannel(channel1.id); // Returns undefined (already consumed)

Navigation Integration

Event channels integrate seamlessly with page navigation for communication between pages.

/**
 * Navigation with event channel integration
 * Automatically handled by uni.navigateTo when events are provided
 */
interface NavigationWithEvents {
  /** Event channel is created automatically and passed in result */
  eventChannel: EventChannel;
}

Usage Examples:

// Page A - Navigate to Page B with event communication
const navigationResult = await uni.navigateTo({
  url: '/pages/detail/detail?id=123',
  events: {
    // Events that Page B can emit back to Page A
    dataUpdate: (updatedData) => {
      console.log('Received updated data from detail page:', updatedData);
      this.updateLocalData(updatedData);
    },
    
    actionPerformed: (actionType, result) => {
      console.log(`Detail page performed ${actionType}:`, result);
      this.handleDetailAction(actionType, result);
    },
    
    pageReady: () => {
      console.log('Detail page is ready');
      // Send initial data to detail page
      navigationResult.eventChannel.emit('initialData', {
        userData: this.userData,
        preferences: this.preferences
      });
    }
  }
});

// Send data to Page B
navigationResult.eventChannel.emit('configUpdate', {
  theme: 'dark',
  language: 'en-US'
});

// Page B - Receive and respond to events
export default {
  onLoad(options) {
    // Get event channel passed from Page A
    const eventChannel = this.getOpenerEventChannel();
    
    // Listen for events from Page A
    eventChannel.on('initialData', (data) => {
      console.log('Received initial data from opener:', data);
      this.userData = data.userData;
      this.preferences = data.preferences;
      this.initializeWithData();
    });
    
    eventChannel.on('configUpdate', (config) => {
      console.log('Config updated:', config);
      this.applyConfiguration(config);
    });
    
    // Emit events back to Page A
    eventChannel.emit('pageReady');
    
    // Emit data updates
    setTimeout(() => {
      eventChannel.emit('dataUpdate', {
        newData: 'Updated from detail page',
        timestamp: Date.now()
      });
    }, 2000);
  },
  
  methods: {
    handleUserAction(actionType) {
      const eventChannel = this.getOpenerEventChannel();
      
      // Process action
      const result = this.processAction(actionType);
      
      // Notify opener page
      eventChannel.emit('actionPerformed', actionType, result);
    }
  }
};

Advanced Event Channel Features

Event Caching

Event channels support automatic event caching when no listeners are present.

// Events emitted before listeners are registered get cached
const channel = initEventChannel();

// Emit event before any listeners are registered
channel.emit('earlyEvent', 'This will be cached');

// Register listener later - cached event will be replayed
channel.on('earlyEvent', (message) => {
  console.log('Received cached event:', message); // "This will be cached"
});

Listener Management

Advanced listener management with type-based behavior.

const channel = initEventChannel();

// Regular listeners persist until manually removed
channel.on('persistentEvent', () => {
  console.log('This listener persists');
});

// One-time listeners are automatically removed after first execution
channel.once('oneTimeEvent', () => {
  console.log('This runs only once');
});

// Emit events multiple times
channel.emit('persistentEvent'); // Listener runs
channel.emit('persistentEvent'); // Listener runs again

channel.emit('oneTimeEvent');     // Listener runs and is removed
channel.emit('oneTimeEvent');     // Nothing happens (listener removed)

Channel Lifecycle

Event channels have a managed lifecycle tied to page navigation.

// Channel creation during navigation
uni.navigateTo({
  url: '/pages/target/target',
  events: {
    // Initial events create the channel
    ready: () => console.log('Target ready')
  }
}).then(result => {
  // Channel is available in navigation result
  const channel = result.eventChannel;
  
  // Channel remains active during page lifetime
  channel.emit('initData', initialData);
});

// In target page
export default {
  data() {
    return {
      eventChannel: null
    };
  },
  
  onLoad() {
    // Retrieve channel created during navigation
    this.eventChannel = this.getOpenerEventChannel();
    
    // Channel is automatically cleaned up when page is destroyed
  },
  
  onUnload() {
    // Channel cleanup happens automatically
    // No manual cleanup required
  }
};

Multi-Channel Communication

Complex applications can use multiple event channels for different purposes.

// Create separate channels for different concerns
const dataChannel = initEventChannel({
  dataUpdate: handleDataUpdate,
  dataError: handleDataError
});

const uiChannel = initEventChannel({
  themeChange: handleThemeChange,
  layoutUpdate: handleLayoutUpdate
});

const analyticsChannel = initEventChannel({
  userAction: trackUserAction,
  pageView: trackPageView
});

// Use channels for specific purposes
dataChannel.emit('dataUpdate', newData);
uiChannel.emit('themeChange', 'dark');
analyticsChannel.emit('userAction', 'button_click');

Event Channel Patterns

Request-Response Pattern

// Requester side
const channel = initEventChannel();

channel.once('response', (data) => {
  console.log('Received response:', data);
});

channel.emit('request', { type: 'getData', params: { id: 123 } });

// Responder side
channel.on('request', (requestData) => {
  const { type, params } = requestData;
  
  if (type === 'getData') {
    const data = fetchData(params.id);
    channel.emit('response', data);
  }
});

Pub-Sub Pattern

// Publisher
const channel = initEventChannel();

setInterval(() => {
  channel.emit('statusUpdate', {
    status: 'active',
    timestamp: Date.now(),
    data: getCurrentStatus()
  });
}, 5000);

// Subscribers
channel.on('statusUpdate', (update) => {
  console.log('Subscriber 1 received:', update);
  updateUI(update);
});

channel.on('statusUpdate', (update) => {
  console.log('Subscriber 2 received:', update);
  logStatusChange(update);
});

State Synchronization Pattern

// State manager
const stateChannel = initEventChannel();
let globalState = { user: null, theme: 'light' };

stateChannel.on('stateChange', (newState) => {
  globalState = { ...globalState, ...newState };
  stateChannel.emit('stateUpdated', globalState);
});

// State consumers
stateChannel.on('stateUpdated', (state) => {
  console.log('State updated:', state);
  updateComponentState(state);
});

// State updaters
stateChannel.emit('stateChange', { theme: 'dark' });
stateChannel.emit('stateChange', { user: { id: 123, name: 'John' } });

Event Channel Architecture

Channel Storage

  • Channels are stored in global maps with unique IDs
  • Cached channels use FIFO retrieval pattern
  • Automatic cleanup prevents memory leaks

Event Processing

  • Events are processed synchronously within channels
  • Cached events are replayed when listeners are added
  • Once-listeners are automatically removed after execution

Navigation Integration

  • Channels are automatically created during navigateTo with events
  • Channel references are passed through navigation results
  • Channels are accessible in target pages via getOpenerEventChannel()

Memory Management

  • Channels are automatically cleaned up when pages are destroyed
  • Event caches are cleared when listeners consume cached events
  • Listener references are properly managed to prevent memory leaks

Install with Tessl CLI

npx tessl i tessl/npm-dcloudio--uni-mp-qq

docs

application-lifecycle.md

build-configuration.md

component-system.md

event-channels.md

index.md

unified-api.md

utilities.md

tile.json