安利一个网页调试开发利器vConsole
vConsole
一个轻量、可拓展、针对手机网页的前端开发者调试面板。
vConsole 是框架无关的,可以在 Vue、React 或其他任何框架中使用。
现在 vConsole 是微信小程序的官方调试工具。
# 功能特性
- 日志(Logs):
console.log|info|error|...
- 网络(Network):
XMLHttpRequest
,Fetch
,sendBeacon
- 节点(Element): HTML 节点树
- 存储(Storage):
Cookies
,LocalStorage
,SessionStorage
- 手动执行 JS 命令行
- 自定义插件
# 使用教程
# 上手
# 使用 NPM 安装(推荐)
$ npm install vconsole
import VConsole from "vconsole";
const vConsole = new VConsole();
// 或者使用配置参数进行初始化
const vConsole = new VConsole({ maxLogNumber: 1000 });
// 调用 console 方法输出日志
console.log("Hello world");
// 完成调试后,可销毁 vConsole
vConsole.destroy();
2
3
4
5
6
7
8
9
10
11
请注意,
VConsole
只是 vConsole 的原型,而非一个已实例化的对象。
所以在手动new
实例化之前,vConsole 不会被插入到网页中。
或者,你可以用 CDN 来引入 vConsole:
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
// VConsole 会自动挂载到 `window.VConsole`
var vConsole = new window.VConsole();
</script>
2
3
4
5
可用的 CDN:
- https://unpkg.com/vconsole@latest/dist/vconsole.min.js
- https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js
# 使用方法
# 初始化 & 配置
引入后, 需要手动初始化 vConsole:
var vConsole = new VConsole(option);
option
是一个选填的 object 对象,具体配置定义请参阅 公共属性及方法。
使用 setOption()
来更新 option
:
vConsole.setOption("maxLogNumber", 5000);
// 或者:
vConsole.setOption({ maxLogNumber: 5000 });
2
3
# 打印日志
与 PC 端打印 log 一致,可直接使用 console.log()
等方法直接打印日志:
console.log("Hello World");
未加载 vConsole 模块时,console.log()
会直接打印到原生控制台中;加载 vConsole 后,日志会打印到页面前端+原生控制台。
如果你希望日志仅输出到 vConsole 中,可使用插件方法:
vConsole.log.log("Hello world");
# 日志类型
支持 5 种不同类型的日志,会以不同的颜色输出到前端面板:
console.log("foo"); // 白底黑字
console.info("bar"); // 白底紫字
console.debug("oh"); // 白底黄字
console.warn("foo"); // 黄底黄字
console.error("bar"); // 红底红字
2
3
4
5
# 其他方法
支持以下 console
方法:
console.clear(); // 清空所有日志
console.time("foo"); // 启动名为 foo 的计时器
console.timeEnd("foo"); // 停止 foo 计时器并输出经过的时间
2
3
# 样式
可使用 %c
来添加样式:
console.log("%c blue %c red", "color:blue", "color:red"); // blue red
console.log("%c FOO", "font-weight:bold", "bar"); // FOO bar
console.log("%c Foo %c bar", "color:red"); // Foo %c bar
2
3
只有第一个参数支持
%c
格式,一旦出现%c
格式,后续的字符串参数将作为 HTML style 样式来替换%c
;未被替换的%c
、剩余的参数,将作为默认日志照常输出。
# 使用字符串替换
可使用 %s, %d, %o
来格式化输出。
%s
:输出为字符串。非字符串对象会被转换成字符串。%d
:输出为数字。%o
:输出为对象。可以点击展开对象详情。
console.log("Hi %s, Im %s", "Foo", "Bar"); // Hi Foo, Im Bar
console.log("I had %d cakes", 3); // I had 3 cakes
console.log("The %o is large", obj); // The [[obj]] is large
2
3
# 特殊格式
支持使用 [system]
作为第一个参数,来将 log 输出到 System 面板:
console.log("[system]", "foo"); // 'foo' 会输出到 System 面板
console.log("[system] bar"); // 这行日志会输出到 Log 面板而非 System 面板
2
若编写自定义 log 面板插件,亦可通过上述格式将 log 输出到自定义面板:
console.log("[myplugin]", "bar"); // 'myplugin' 为自定义面板插件的 id
# 内置插件
# Network 网络请求
所有 XMLHttpRequest | fetch | sendBeacon
请求都会被显示到 Network 面板中。
若不希望一个请求显示在面板中,可添加属性 _noVConsole = true
到 XHR 对象中:
var xhr = new XMLHttpRequest();
xhr._noVConsole = true; // 不会显示到 tab 中
xhr.open("GET", "http://example.com/");
xhr.send();
2
3
4
如果你想展示自定义的 request 请求,可尝试 Network 插件方法:
vConsole.network.add(...);
# 公共属性及方法
vConsole 提供一些公共属性字段、函数方法,以便开发插件。
# 属性
# vConsole.version
当前 vConsole 的版本号。
- 只读
- 类型:string
例子:
vConsole.version; // => "3.11.0"
# vConsole.option
配置项。
- 可写
- 类型:object
键名 | 类型 | 可选 | 默认值 | 描述 |
---|---|---|---|---|
defaultPlugins | Array | true | ['system', 'network', 'element', 'storage'] | 需要自动初始化并加载的内置插件。 |
onReady | Function | true | 回调方法,当 vConsole 完成初始化并加载完内置插件后触发。 | |
onClearLog | Function | true | 回调方法,点击 Log 或 System 面板的 "Clear" 按钮后出发。 | |
maxLogNumber | Number | true | 1000 | 超出数量上限的日志会被自动清除。 |
maxNetworkNumber | Number | true | 1000 | 超出数量上限的请求记录会被自动清除。 |
disableLogScrolling | Boolean | true | 若为 false ,有新日志时面板将不会自动滚动到底部。 | |
theme | String | true | 'light' | 主题颜色,可选值为 'light' |
target | String, HTMLElement | true | document.documentElement | 挂载到的节点,可为 HTMLElement 或 CSS selector。 |
例子:
// get
vConsole.option; // => {...}
// set
vConsole.setOption("maxLogNumber", 5000);
// 或者:
vConsole.setOption({ maxLogNumber: 5000 });
2
3
4
5
6
# 方法
# vConsole.setOption(keyOrObj[, value])
更新 vConsole.option
配置项。
# 参数:
- (required) keyOrObj: 配置项的 key 值,或直接传入 key-value 格式的 object 对象。
- (optional) value: 配置项的 value 值。
# 返回:
- 无
# 例子:
vConsole.setOption("maxLogNumber", 5000);
// 或者:
vConsole.setOption({ maxLogNumber: 5000 });
2
3
# vConsole.setSwitchPosition(x, y)
设置开关按钮的位置。
# 参数:
- (required) x: X 坐标,坐标原点位于屏幕右下角。
- (required) y: Y 坐标,坐标原点位于屏幕右下角。
# 返回:
- 无
# 例子:
vConsole.setSwitchPosition(20, 20);
# vConsole.destroy()
析构一个 vConsole 对象实例,并将 vConsole 面板从页面中移除。
# 参数:
- 无
# 返回:
- 无
# 例子:
var vConsole = new VConsole();
// ... do something
vConsole.destroy();
2
3
# vConsole.addPlugin(plugin)
添加一个新插件。重名的插件会被忽略。
# 参数:
- (required) plugin: 一个 VConsolePlugin 对象。
# 返回:
- Boolean: 成功为
true
,失败为false
。
# 例子:
var myPlugin = new VConsolePlugin("my_plugin", "My Plugin");
vConsole.addPlugin(myPlugin);
2
# vConsole.removePlugin(pluginID)
卸载一个插件。
# 参数:
- (required) pluginID: 插件的 plugin id。
# 返回:
- Boolean: 成功为
true
,失败为false
。
# 例子:
vConsole.removePlugin("my_plugin");
# vConsole.showPlugin(pluginID)
根据 plugin id 激活显示一个面板。
此方法会触发先前激活态面板的 hide
事件,并触发当前激活态面板的 show
事件。
# 参数:
- (required) pluginID: 字符串,面板的 plugin id。
# 返回:
- 无
# 例子:
vConsole.showPlugin("system"); // 显示 System 面板
# vConsole.show()
显示 vConsole 主面板。这个方法会触发插件事件 showConsole
。
# 参数:
- 无
# 返回:
- 无
# 例子:
vConsole.show();
# vConsole.hide()
隐藏 vConsole 主面板。这个方法会触发插件事件 hideConsole
。
# 参数:
- 无
# 返回:
- 无
# 例子:
vConsole.hide();
# vConsole.showSwitch()
显示 vConsole 的开关按钮。
# 参数:
- 无
# 返回:
- 无
# 例子:
vConsole.showSwitch();
# vConsole.hideSwitch()
隐藏 vConsole 的开关按钮
隐藏后,用户将无法手动唤起 vConsole 面板。因此按钮或面板必须通过 vConsole.showSwitch()
或 vConsole.show()
来展示出来。
# 参数:
- 无
# 返回:
- 无
# 例子:
vConsole.hideSwitch();
# 插件
通过插件,你可以:
- 添加一个新的 tab 面板
- 添加一个或多个 tool 按钮(位于面板底部)
在 tab 和 tool 按钮中,即可添加自定义功能,以满足个性化开发的需要。
# 快速上手
两行创建一个 vConsole 插件:
var myPlugin = new VConsole.VConsolePlugin("my_plugin", "My Plugin");
vc.addPlugin(myPlugin);
2
# 编写插件
==============================
3 步即可编写一个 vConsole 插件:
- 实例化 vConsole 插件
- 绑定事件到插件
- 将插件添加到 vConsole
# 1. 实例化插件
插件原型挂载在 VConsole.VConsolePlugin
中:
VConsole.VConsolePlugin(id, name);
id
(必填) 字符串,插件的 id,必须保证唯一,不能与其他插件冲突。name
(选填) 字符串,展示为 tab 面板的名字。
所以这一步只需将插件 new
出来即可:
var myPlugin = new VConsole.VConsolePlugin("my_plugin", "My Plugin");
# 2. 绑定插件事件
在初始化插件、后续运行时,vConsole 会对插件触发一些事件(event)。插件须通过这些事件来完成自定义功能。
使用 .on()
方法来绑定一个事件:
on(eventName, callback);
eventName
(必填) 字符串,事件的名字。callback
(必填) 回调函数,事件被触发时执行。
例子:
myPlugin.on("init", function () {
console.log("My plugin init");
});
2
3
在本教程中,我们准备编写一个既有 tab 面板,又有 tool 按钮(位于面板底部)的插件。
添加新 tab 面板,需要绑定 renderTab
事件:
myPlugin.on("renderTab", function (callback) {
var html = "<div>Click the tool button below!</div>";
callback(html);
});
2
3
4
插件初始化过程中,就会触发 renderTab
事件。在这里我们简单地回传了一个 HTML 字符串给 callback
,然后这段 HTML 就会被选染成新 tab 面板的主体部分。这个新 tab 的名字就是刚才实例化时的 name
。
此外,若不绑定 renderTab
,那么 vConsole 就不会添加新 tab。
接下来要添加一个底部的 tool 按钮,需要绑定 addTool
事件:
myPlugin.on("addTool", function (callback) {
var button = {
name: "Reload",
onClick: function (event) {
location.reload();
},
};
callback([button]);
});
2
3
4
5
6
7
8
9
同样地,addTool
会在插件初始化过程中触发,且在 renderTab
之后。回调函数 callback
的参数接收一个 array
数组,数组元素是用于配置按钮的 object
对象。本例中,点击这个按钮会重新加载当前网页。
# 3. 添加到 vConsole
最后一步,就是将写好的插件添加到 vConsole 中:
vConsole.addPlugin(pluginObject);
pluginObject
(必填) 必须为 VConsolePlugin
实例化的对象。
例子:
vConsole.addPlugin(myPlugin);
在添加到 vConsole 之前,请确保已经绑定完所有需要用到的事件。一些初始化相关的事件只会在插件被添加时触发一次,并不会在其他时机被触发。
# 插件:Event 事件列表
==============================
插件的所有事件(event)都是可选的,不强制绑定。但一些特性(比如添加 tool 按钮)依赖于指定的事件,所以若要实现那些特性,就必须绑定指定的事件。
每个事件都会有一个 callback 回调函数,当事件被触发时,就会执行 callback。一些 callback 可能会带有参数。
# init
当插件开始初始化时触发。这个事件触发时,代表 vConsole 开始安装此插件,开发者可以在此时初始化一些配置。 这个事件只会触发一次。
注意,此时插件的 DOM 仍未就绪,插件还未被渲染到页面中。
# Callback 参数:
- 无
# 例子:
myPlugin.on("init", function () {
// 在这里可以初始化一些自用的配置
this.list = []; // `this` == `myPlugin`
});
2
3
4
# renderTab
当 vConsole 尝试为此插件渲染新 tab 时触发。这个事件只会触发一次。
绑定此事件后,vConsole 会认为此插件需要创建新 tab,并会将 callback 中获取的 HTML 用于渲染 tab。因此,只要绑定了此事件,新 tab 肯定会被渲染到页面中,无论 callback 传入的 HTML 是否为空。如果不需要添加新 tab,请不要绑定此事件。
# Callback 参数
- (必填) function(html): 回调函数,接收一个 HTML 参数用于渲染 tab。
html
可以为 HTML 字符串,或者HTMLElement
对象(或支持appendTo()
方法的对象,如 jQuery 对象)。
# 例子:
myPlugin.on("renderTab", function (callback) {
var html = "<div>Hello</div>";
callback(html);
});
2
3
4
# addTopBar
当 vConsole 尝试为此插件添加新的 topbar 按钮时触发。这个事件只会触发一次。
# Callback 参数:
- (必填) function(btnList): 回调函数,接收一个带有按钮配置信息的
array
数组。
按钮的参数为:
Property | |||
---|---|---|---|
name | string | 必填 | 按钮展示的名字。 |
data | object | 选填 | 按钮的自定义数据,key-value 格式。 |
className | string | 选填 | 按钮的 className。 |
actived | boolean | optional | 按钮是否处在选中样式。 |
onClick | (event, data) => boolean | 必填 | 点击按钮时的回调函数。触发回调后,除非回调函数返回 false ,此按钮将自动变为选中的样式。 |
# 例子:
var type;
myPlugin.on('addTopBar', function(callback) {
var btnList = [];
btnList.push({
name: 'Apple',
className: '',
data: {type: 'apple'},
onClick: function(event, data) {
if (type != data.type) {
// `this` 指向当前按钮
type = data.type;
} else {
return false;
}
}
});
btnList.push({
name: 'Orange',
className: '',
data: {type: 'orange'},
onClick: function(event, data) {
type = data.type;
}
}
});
callback(btnList);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# addTool
当 vConsole 尝试为此插件添加新的 tool 按钮时触发。这个事件只会触发一次。
# Callback 参数:
- (必填) function(toolList): 回调函数,接收一个带有按钮配置信息的
array
数组。
tool 按钮的参数为:
Property | |||
---|---|---|---|
name | string | 必填 | 按钮展示的名字。 |
data | object | 选填 | 按钮的自定义数据,key-value 格式。 |
global | boolean | 选填,默认 false | false 时,当切换到别的 tab 后,按钮就会被隐藏;true 时,按钮变成全局可见。 |
onClick | (event, data) => void | 必填 | 点击按钮时的回调函数。 |
# 例子:
myPlugin.on("addTool", function (callback) {
var toolList = [];
toolList.push({
name: "Reload",
global: false,
onClick: function (event, data) {
location.reload();
},
});
callback(toolList);
});
2
3
4
5
6
7
8
9
10
11
# ready
当插件初始化结束后触发。这个事件只会触发一次。此时插件已经成功安装并已渲染到页面。
# Callback 参数:
- 无
# 例子:
myPlugin.on("ready", function () {
// do something...
});
2
3
# remove
当插件即将卸载前触发。这个事件只会触发一次。
需要注意的是,如果在 vConsole ready 之前就卸载插件,那么此事件会在 init
之前就被调用。
# Callback 参数:
- 无
# 例子:
myPlugin.on("remove", function () {
// do something...
});
2
3
# show
当插件的 tab 被显示时触发。只有绑定了 renderTab
事件的插件才会收到此事件。
# Callback 参数:
- 无
# 例子:
myPlugin.on("show", function () {
// do something
});
2
3
# hide
当插件的 tab 被隐藏时触发。只有绑定了 renderTab
事件的插件才会收到此事件。
# Callback 参数:
- 无
# 例子:
myPlugin.on("hide", function () {
// do something
});
2
3
# showConsole
当 vConsole 被显示时触发。
# Callback 参数:
- 无
# 例子:
myPlugin.on("showConsole", function () {
// do something
});
2
3
# hideConsole
当 vConsole 被隐藏时触发。
# Callback 参数:
- 无
# 例子:
myPlugin.on("hideConsole", function () {
// do something
});
2
3
# updateOption
当 vConsole.setOption()
被调用时触发
# Callback 参数:
- none
# 例子:
myPlugin.on("updateOption", function () {
// do something
});
2
3
# 第三方插件列表
- vConsole-sources (opens new window)
- vconsole-webpack-plugin (opens new window)
- vconsole-stats-plugin (opens new window)
- vconsole-vue-devtools-plugin (opens new window)
- vconsole-outputlog-plugin (opens new window)
- vite-plugin-vconsole (opens new window)