vConsole核心源码学习

2024-06-14 17:28
文章标签 源码 学习 核心 vconsole

本文主要是介绍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');
}
  • showhide 方法用于显示和隐藏调试面板。
  • showSwitchhideSwitch 方法用于显示和隐藏开关按钮。
  • showPlugin 方法用于显示指定插件的面板。

总结

vConsole 是一个功能强大的移动端调试工具,通过插件机制提供了日志、网络、系统信息、元素查看和存储等功能。核心类 VConsole 负责初始化、插件管理、事件触发和销毁等操作,使用 Svelte 组件来构建调试面板,并提供了一系列方法来管理插件和显示调试信息。

这篇关于vConsole核心源码学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061044

相关文章

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

java中Optional的核心用法和最佳实践

《java中Optional的核心用法和最佳实践》Java8中Optional用于处理可能为null的值,减少空指针异常,:本文主要介绍java中Optional核心用法和最佳实践的相关资料,文中... 目录前言1. 创建 Optional 对象1.1 常规创建方式2. 访问 Optional 中的值2.1

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Java Jackson核心注解使用详解

《JavaJackson核心注解使用详解》:本文主要介绍JavaJackson核心注解的使用,​​Jackson核心注解​​用于控制Java对象与JSON之间的序列化、反序列化行为,简化字段映射... 目录前言一、@jsonProperty-指定JSON字段名二、@JsonIgnore-忽略字段三、@Jso

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen