关于vConsole源码的理解分享(vConsole⼀个移动端调试控制台⼯具)(1)⼀个轻量、可拓展、针对⼿机⽹页的前端开发者调试⾯板。
特性
查看 console ⽇志
查看⽹络请求
查看页⾯ element 结构
查看 Cookies 和 localStorage
⼿动执⾏ JS 命令⾏
⾃定义插件
这是github的readme介绍,对于调试移动端以及上线后出现的⼀些问题确实是⼀个很好的⼯具!! 为腾讯开源点个赞。
使⽤⽅法请参考: (请原谅我把它叫的那么长哈哈哈)
源码分析
总的来说,vConsole的源码还是很清晰的,采⽤了es6的语法,以⾯向对象的形式即类的显⽰来组织代码,按照控制台的ui来分割,这⼀点值得借鉴和学习。
源码代码结构
简单的画了⼀个草图,⾸先要明确是 VConsole为核⼼类,负责插件的⽣成,事件绑定,运⾏等,⽽vConsolePlugin 类似⼀个抽象类,具体实现渲染绑定等由⼦类去具体实现。所以VConsole的扩展是通过添加VConsolePlugin的实现来的。(如果有歧义请指正批评)
模板引擎
vConsole采⽤的是⼀个叫做 Mito.js 的 ⼀个简单的模板引擎(估计是腾讯⾃⼰内部写的⼀个模板引擎),这个⽂件在lib⽂件夹下,代码很简短就⼀个rener⽅法,然后配合模板html使⽤
//使⽤指定数据将模板⽂本编译成 element 对象或者 HTML 字符串。
//(required) tpl: 模板字符串。
//(required) data: ⼀组 key-value 形式的数据源。
//(optional) toString: 布尔值,⽤于设定返回值为 element 对象还是 HTML 字符串,默认为 `false`。
//返回值 Element 对象或者 HTML 字符串
function render(tpl, data, toString)
模板语法涉及到了常⽤的if else ,for和switch 常⽤的流程语句,对付⼀些简单的需求这个已经⾜够了,详细语法使⽤参考官⽅⽂档的helper_function.md
核⼼模块
asp查看源码配置ui核⼼模块主要是core.js的这个js⽂件,也就是VConsole类的定义。
⾸先来看下这个类的Construction⽅法,我把注释写在代码⾥ ,这样看起来 应该很清晰了
constructor(opt) {
//判断是否已经存在VConsole实例了,通过判断document⽂档结构是否存在了VCONSOLE_ID即(#__vconsole)这个id。
if (!!$.one(VCONSOLE_ID)) {
console.debug('vConsole is already exists.');
return;
}
//将this⽤that保存起来,这⾥的作⽤不⾔⽽喻,就是为了防⽌接下来的操作(⽅法)调⽤会改变this的指向
let that = this;
//版本号
this.version = pkg.version;
//基础的dom 可以理解为root 即id为VCONSOLE_ID的⽂档元素
this.$dom = null;
//再次判断是否已经初始化的标识,和⼀开始的⽅法⼀样的作⽤
this.isInited = false;
//配置选项以下是对加载哪⼏个默认插件的配置
this.option = {
defaultPlugins: ['system', 'network', 'element', 'storage']
};
//当前活动的tab页框
this.activedTab = '';
//tab页框数组
this.tabList = [];
//插件列表
this.pluginList = {};
//vConsole的悬浮按钮的配置(位置)
this.switchPos = {
x: 10, // right
y: 10, // bottom
startX: 0,
startY: 0,
endX: 0,
endY: 0
};
// 暴露⼀些公⽤的⽅法出去,⽐如判断是否对象,数组等详见在../lib/tool.js的⽂件
//暴露$的⽅法,query.js⽂件夹
this.$ = $;
// 合并⽤户配置和默认配置。for in ⽤法了解下
if (tool.isObject(opt)) {
for (let key in opt) {
this.option[key] = opt[key];
}
}
//初始化添加插件插件的初始化添加到tabList
this._addBuiltInPlugins();
// Vconsole的UI加载,
let _onload = function() {
if (that.isInited) {
return;
}
/
/渲染VConsole的主⾯板,swicth按钮
that._render();
that._render();
//⾯板上的交互模拟触摸滑动
that._mockTap();
//绑定事件拖动swicth按钮,点击⾯板的tab等
that._bindEvent();
//⾯板渲染完成后的插件⾃动加载渲染
that._autoRun();
};
//当document渲染加载完成调⽤_onload⽅法
if (document !== undefined) {
if (adyState == 'complete') {
_onload();
} else {
$.bind(window, 'load', _onload);
}
} else {
// if document does not exist, wait for it
let _timer;
let _pollingDocument = function() {
if (!!document && adyState == 'complete') { _timer && clearTimeout(_timer);
_onload();
} else {
_timer = setTimeout(_pollingDocument, 1);
}
};
_timer = setTimeout(_pollingDocument, 1);
}
}
总的流程⽤流程图表⽰
⼤概VConsole类的流程和做的⼀些事情都阐述完了,接下来分析⼀些重要的⽅法addPlugin();
添加⼀个新的插件,这个为基本组件如何加到VConsole的公⽤⽅法,实现加⼊到VConsole体系,并且运⾏起来。
/**
* add a new plugin
* @public
* @param object VConsolePlugin object
* @return boolean
*/
addPlugin(plugin) {
// ignore this plugin if it has already been installed
if (this.pluginList[plugin.id] !== undefined) {
console.debug('Plugin ' + plugin.id + ' has already been added.');
return false;
}
this.pluginList[plugin.id] = plugin;
// init plugin only if vConsole is ready
if (this.isInited) {
this._initPlugin(plugin);
// if it's the first plugin, show it by default
if (this.tabList.length == 1) {
this.showTab(this.tabList[0]);
}
}
return true;
}
⽽在这个⽅法中最重要的⽅法就是下⾯这个⽅法_initPlugin();初始化插件,包括加⼊panel中的点击事件等⼀些操作,其中的insertAdjacentElement()⽅法相当于jq中的insertAfter和insertBefore等⽅法
/**
* init a plugin
* @private
*/
_initPlugin(plugin) {
let that = this;
plugin.vConsole = this;
// start init
// render tab (if it is a tab plugin then it should has tab-related events)
// add to tabList
that.tabList.push(plugin.id);
// render tabbar
let $tabbar = $.render(tplTabbar, { id: plugin.id, name: plugin.name });
$.one('.vc-tabbar', that.$dom).insertAdjacentElement('beforeend', $tabbar);
// render tabbox
let $tabbox = $.render(tplTabbox, { id: plugin.id });
if (!!tabboxHTML) {
if (tool.isString(tabboxHTML)) {
$tabbox.innerHTML += tabboxHTML;
} else if (tool.isFunction(tabboxHTML.appendTo)) {
tabboxHTML.appendTo($tabbox);
} else if (tool.isElement(tabboxHTML)) {
$tabbox.insertAdjacentElement('beforeend', tabboxHTML);
}
}
$.one('.vc-content', that.$dom).insertAdjacentElement('beforeend', $tabbox);
});
/
/ render top bar
if (!btnList) {
return;
}
let $topbar = $.one('.vc-topbar', that.$dom);
for (let i = 0; i < btnList.length; i++) {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论