本文主要是介绍vConsole核心源码学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 概述
- 核心类 `VConsole`
- 1. 导入模块和定义常量
- 2. 类的定义和构造函数
- 3. 添加内置插件
- 4. 初始化 Svelte 组件
- 5. 自动运行
- 6. 添加和移除插件
- 7. 显示和隐藏面板
- 总结
vConsole
核心类的实现,该工具由腾讯开发,用于在移动端进行调试。代码主要涉及 vConsole
的初始化、插件管理、事件触发和销毁等功能。以下是对代码的详细解析:
概述
vConsole
是一个用于移动端的调试工具。- 提供日志、网络、系统信息、元素查看和存储等调试功能。
- 使用 Svelte 作为前端框架来构建调试面板。
核心类 VConsole
1. 导入模块和定义常量
import type { SvelteComponent } from 'svelte';
import type { VConsoleOptions } from './options.interface';
import * as tool from '../lib/tool';
import $ from '../lib/query';
import { default as CoreCompClass } from './core.svelte';
import type { IVConsoleTopbarOptions, IVConsolePluginEventName } from '../lib/plugin';
import { VConsolePlugin } from '../lib/plugin';
import { VConsoleLogPlugin } from '../log/log';
import { VConsoleDefaultPlugin } from '../log/default';
import { VConsoleSystemPlugin } from '../log/system';
import { VConsoleNetworkPlugin } from '../network/network';
import { VConsoleElementPlugin } from '../element/element';
import { VConsoleStoragePlugin } from '../storage/storage';
import { VConsoleLogExporter } from '../log/log.exporter';
import { VConsoleNetworkExporter } from '../network/network.exporter';const VCONSOLE_ID = '#__vconsole';
- 导入必要的模块和类型。
- 定义常量
VCONSOLE_ID
,用于标识vConsole
的 DOM 元素。
2. 类的定义和构造函数
export class VConsole {public version: string = __VERSION__;public isInited: boolean = false;public option: VConsoleOptions = {};protected compInstance: SvelteComponent;protected pluginList: { [id: string]: VConsolePlugin } = {}; // plugin instance// Export plugin methodspublic log: VConsoleLogExporter;public system: VConsoleLogExporter;public network: VConsoleNetworkExporter;// Export static classespublic static VConsolePlugin: typeof VConsolePlugin;public static VConsoleLogPlugin: typeof VConsoleLogPlugin;public static VConsoleDefaultPlugin: typeof VConsoleDefaultPlugin;public static VConsoleSystemPlugin: typeof VConsoleSystemPlugin;public static VConsoleNetworkPlugin: typeof VConsoleNetworkPlugin;public static VConsoleElementPlugin: typeof VConsoleElementPlugin;public static VConsoleStoragePlugin: typeof VConsoleStoragePlugin;constructor(opt?: VConsoleOptions) {if (!!VConsole.instance && VConsole.instance instanceof VConsole) {console.debug('[vConsole] vConsole is already exists.');return VConsole.instance;}VConsole.instance = this;this.isInited = false;this.option = {defaultPlugins: ['system', 'network', 'element', 'storage'],log: {},network: {},storage: {},};// merge optionsif (tool.isObject(opt)) {for (let key in opt) {this.option[key] = opt[key];}}// check deprecated optionsif (typeof this.option.maxLogNumber !== 'undefined') {this.option.log.maxLogNumber = this.option.maxLogNumber;console.debug('[vConsole] Deprecated option: `maxLogNumber`, use `log.maxLogNumber` instead.');}if (typeof this.option.onClearLog !== 'undefined') {console.debug('[vConsole] Deprecated option: `onClearLog`.');}if (typeof this.option.maxNetworkNumber !== 'undefined') {this.option.network.maxNetworkNumber = this.option.maxNetworkNumber;console.debug('[vConsole] Deprecated option: `maxNetworkNumber`, use `network.maxNetworkNumber` instead.');}// add built-in pluginsthis._addBuiltInPlugins();// try to initconst _onload = () => {if (this.isInited) {return;}this._initComponent();this._autoRun();};if (document !== undefined) {if (document.readyState === 'loading') {$.bind(<any>window, 'DOMContentLoaded', _onload);} else {_onload();}} else {// if document does not exist, wait for itlet _timer;const _pollingDocument = () => {if (!!document && document.readyState == 'complete') {_timer && clearTimeout(_timer);_onload();} else {_timer = setTimeout(_pollingDocument, 1);}};_timer = setTimeout(_pollingDocument, 1);}}
- 定义
VConsole
类,并在构造函数中进行初始化。 - 检查是否已有实例存在,如果有则返回现有实例。
- 初始化选项并合并用户传入的选项。
- 检查并处理已弃用的选项。
- 添加内置插件。
- 尝试初始化组件,等待文档加载完成后进行初始化。
3. 添加内置插件
/*** Add built-in plugins.*/
private _addBuiltInPlugins() {// add default log pluginthis.addPlugin(new VConsoleDefaultPlugin('default', 'Log'));// add other built-in plugins according to user's configconst list = this.option.defaultPlugins;const plugins = {'system': { proto: VConsoleSystemPlugin, name: 'System' },};if (__TARGET__ === 'web') {plugins['network'] = { proto: VConsoleNetworkPlugin, name: 'Network' };plugins['element'] = { proto: VConsoleElementPlugin, name: 'Element' };plugins['storage'] = { proto: VConsoleStoragePlugin, name: 'Storage' };}if (!!list && tool.isArray(list)) {for (let i = 0; i < list.length; i++) {const pluginConf = plugins[list[i]];if (!!pluginConf) {this.addPlugin(new pluginConf.proto(list[i], pluginConf.name));} else {console.debug('[vConsole] Unrecognized default plugin ID:', list[i]);}}}
}
- 根据用户配置添加内置插件。
- 支持日志、系统、网络、元素查看和存储等插件。
4. 初始化 Svelte 组件
/*** Init svelte component.*/
private _initComponent() {if (! $.one(VCONSOLE_ID)) {const switchX = <any>tool.getStorage('switch_x') * 1;const switchY = <any>tool.getStorage('switch_y') * 1;let target: HTMLElement;if (typeof this.option.target === 'string') {target = document.querySelector(this.option.target);} else if (this.option.target instanceof HTMLElement) {target = this.option.target;}if (! (target instanceof HTMLElement)) {target = document.documentElement;}this.compInstance = new CoreCompClass({target,props: {switchButtonPosition: {x: switchX,y: switchY,},},});// bind eventsthis.compInstance.$on('show', (e) => {if (e.detail.show) {this.show();} else {this.hide();}});this.compInstance.$on('changePanel', (e) => {const pluginId = e.detail.pluginId;this.showPlugin(pluginId);});}// set options into componentthis._updateComponentByOptions();
}
- 初始化 Svelte 组件并绑定事件。
- 设置开关按钮的位置并绑定显示和切换面板事件。
5. 自动运行
/*** Auto run after initialization.* @private*/
private _autoRun() {this.isInited = true;// init pluginsfor (let id in this.pluginList) {this._initPlugin(this.pluginList[id]);}// show first pluginthis._showFirstPluginWhenEmpty();this.triggerEvent('ready');
}
- 初始化所有插件。
- 如果没有激活的插件,显示第一个插件。
- 触发
ready
事件。
6. 添加和移除插件
/*** Add a new plugin.*/
public addPlugin(plugin: VConsolePlugin) {// ignore this plugin if it has already been installedif (this.pluginList[plugin.id] !== undefined) {console.debug('[vConsole] Plugin `' + plugin.id + '` has already been added.');return false;}this.pluginList[plugin.id] = plugin;// init plugin only if vConsole is readyif (this.isInited) {this._initPlugin(plugin);// if it's the only plugin, show it by defaultthis._showFirstPluginWhenEmpty();}return true;
}/*** Remove a plugin.*/
public removePlugin(pluginID: string) {pluginID = (pluginID + '').toLowerCase();const plugin = this.pluginList[pluginID];// skipif is has not been installedif (plugin === undefined) {console.debug('[vConsole] Plugin `' + pluginID + '` does not exist.');return false;}// trigger `remove` event before uninstallplugin.trigger('remove');try {delete this.pluginList[pluginID];delete this.compInstance.pluginList[pluginID];} catch (e) {this.pluginList[pluginID] = undefined;this.compInstance.pluginList[pluginID] = undefined;}this.compInstance.pluginList = this.compInstance.pluginList;// show the first plugin by defaultif (this.compInstance.activedPluginId == pluginID) {this.compInstance.activedPluginId = '';this._showFirstPluginWhenEmpty();}return true;
}
addPlugin
方法用于添加新插件,初始化插件并在需要时显示第一个插件。removePlugin
方法用于移除插件,并在需要时显示第一个插件。
7. 显示和隐藏面板
/*** Show console panel.*/
public show() {if (!this.isInited) {return;}this.compInstance.show = true;this._triggerPluginsEvent('showConsole');
}/*** Hide console panel.*/
public hide() {if (!this.isInited) {return;}this.compInstance.show = false;this._triggerPluginsEvent('hideConsole');
}/*** Show switch button*/
public showSwitch() {if (!this.isInited) {return;}this.compInstance.showSwitchButton = true;
}/*** Hide switch button.*/
public hideSwitch() {if (!this.isInited) {return;}this.compInstance.showSwitchButton = false;
}/*** Show a plugin panel.*/
public showPlugin(pluginId: string) {if (!this.isInited) {return;}if (!this.pluginList[pluginId]) {console.debug('[vConsole] Plugin `' + pluginId + '` does not exist.');}// trigger plugin eventthis.compInstance.activedPluginId && this._triggerPluginEvent(this.compInstance.activedPluginId, 'hide');this.compInstance.activedPluginId = pluginId;this._triggerPluginEvent(this.compInstance.activedPluginId, 'show');
}
show
和hide
方法用于显示和隐藏调试面板。showSwitch
和hideSwitch
方法用于显示和隐藏开关按钮。showPlugin
方法用于显示指定插件的面板。
总结
vConsole
是一个功能强大的移动端调试工具,通过插件机制提供了日志、网络、系统信息、元素查看和存储等功能。核心类 VConsole
负责初始化、插件管理、事件触发和销毁等操作,使用 Svelte 组件来构建调试面板,并提供了一系列方法来管理插件和显示调试信息。
这篇关于vConsole核心源码学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!