Vue devtools在production模式下的使用以及控制台调试vue实例(源码分析)
在vue的调试中vue devtools插件很有用,打开与否是由Vue.config.devtools变量来控制。根据官网api显示,Vue.config对象可以在在启动应用之前修改属性的值来控制Vue的行为。大家可能都有过这样的经历,在用vue脚手架调试Vue时我们可以打开vue devtools,但是打包后发布到网上我们就打不开了。实际上Vue devtools常用三种状态。
- 没有发现页面使用Vue

- 发现Vue并且可以打开devtools,这个时候我们按F12就可以在浏览器的devtool中找到Vue



很多时候我们想看看别人写的Vue页面(在Vue production模式下用Vue devtools进行调试),这个时候就要看看Vue和Vue devtools的源码了。我们主要有2个问题,
- Vue devtools是如何检测到页面使用了Vue的
- Vue devtools的打开和关闭原理
对于第2个问题很好猜到,大致使用了如下代码
Vue.config.devtools = process.env.NODE_ENV !== 'production'
在Vue源码中我们在 Vue/src/core/config.js中找到了如下代码 源码链接
devtools: process.env.NODE_ENV !== 'production'
第2个问题解决了,对于第一个问题,我们去Vue devtools的代码仓库下寻找,在vue-devtools/packages/shell-chrome/src/detector.js下找到了如下代码源码链接
const all = document.querySelectorAll('*')
let el
for (let i = 0; i < all.length; i++) {
if (all[i].__vue__) {
el = all[i]
break
}
}
if (el) {
let Vue = Object.getPrototypeOf(el.__vue__).constructor
while (Vue.super) {
Vue = Vue.super
}
win.postMessage(
{
devtoolsEnabled: Vue.config.devtools,
vueDetected: true
},
'*'
)
}
我们可以看到检测有没有使用Vue的算法是遍历dom中的所有节点,只要有一个元素中有__vue__属性循环退出即可以判断页面使用了Vue。接下来我们去Vue源码中寻找__vue__,在和生命周期有关的文件src/src/core/instance/lifecycle.js中我们找到了如下代码源码链接
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
const vm: Component = this
const prevEl = vm.$el
const prevVnode = vm._vnode
const restoreActiveInstance = setActiveInstance(vm)
vm._vnode = vnode
// Vue.prototype.__patch__ is injected in entry points
// based on the rendering backend used.
if (!prevVnode) {
// initial render
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
} else {
// updates
vm.$el = vm.__patch__(prevVnode, vnode)
}
restoreActiveInstance()
// update __vue__ reference
if (prevEl) {
prevEl.__vue__ = null
}
if (vm.$el) {
vm.$el.__vue__ = vm
}
// if parent is an HOC, update its $el as well
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el
}
// updated hook is called by the scheduler to ensure that children are
// updated in a parent's updated hook.
}
通过分析源码得知vm是当前的Vue实例,vm.$el是实例挂载的dom元素,通过其中的vm.$el.vue = vm 将dom的__vue__属性指向Vue实例。现在原理弄懂了,我们来解决实际问题---在production模式下使用Vue devtools。
在启动应用之前修改Vue.config.devtools就可以打开Vue devtools,这里用断点调试的方法强行在页面渲染完成之前修改Vue.config.devtools的值
- 找到网页js中有关Vue的代码,
- 在合适的行打上断点
- 修改Vue.config.devtools的值
- 恢复断点重新打开浏览器调试工具就会看到Vue devtools已经被打开
以下举个例子 我打开了一个使用Vue但是使用production模式的网页






因为我这边chrome断点后刷新很容易卡死,所有最后几张图是在firfox下完成的,新人小白第一篇文章,不喜勿喷
联系方式
github github.com/2239559319