前言
依稀记得,那是一个夏天。。。。。
其实也就是几个月之前,我水了一篇文章
因为一个写法,我翻烂了vue源码,这是vue的问题吧,我要不要提pr!
初衷是记录了个关于vue
的诡异的bug(后来被官方修正了)

没成想歪打正着,都在说bug平平无奇,但调试过程值得学习

本以那都是各位jym
的商业互吹
,却不曾想稀里糊涂
的上了热搜榜,然后又稀里糊涂
的成了热搜第一,也可以称为搂草打兔子
是也!
文章火了,于是很多jy
让我专门出个vue调试教程,给大家传授一些技巧心得,我哪懂什么传授啊,那都是无心插柳柳成荫
如果有,也只在行业混迹多年,被逼无奈,摸爬滚打出来的经验(毕竟有问题搞不定,那是要被开除的,有问题搞定的慢,那也是要扣钱的)
所以几个月来诚惶诚恐不敢动笔,生怕班门弄斧,误人子弟
可这都马上年底了,一数今年的输出,两篇
, 不是说写两篇
不行,而是非常的不行
。
再不写,今年东家的春节大礼包可就没有了, 既然这样的话,在水几篇
吧!
在水文之前,我们先来简单的介绍一下,为什么要学习前端调试的一些技巧。
其实在躺平的互联网的环境和情况下,我们压根不需要什么调试特殊的技巧,因为代码是我写的,我们只需要梳理逻辑总是能发现一些蛛丝马迹
找到问题,结合Chrome DevTools
和伟大的console.log、debugger
最终解决也就是时间问题
即使最终我们解决不了问题,我们也可以解决提问题的人,用一个冠冕堂皇的技术答案给他忽悠过去就行------------ 这个需求实现不了!
但是,我们却是一个内卷的互联网环境,在这种环境下,人员是过剩的,大佬是遍地的。加班是随时的
解决问题的速度,以及干活的效率,直接决定了你绩效的多少,工资高不高
有人都地方就有斗争,与其被队友卷死,还不如直接卷死队友。
所谓先下手为强是也
样式调试
样式调试是调试技巧中的最简单的一环,因为我们只需要简单的按下F12
就能将所有的样式信息一览无余

指哪打哪,所见所得,可以手动调试,添加元素,修改hover
我们就不再赘述,因为太简单了,
vue代码调试
vue
是传承自js
的,因为从某种意义来说,vue
就是js,那么vue
调试,也就是js
调试的技巧,包含js,但超越js
。之所以需要超越,是因为,vue 包含模板
别急,我们一个个来介绍
js部分的调试
所谓js
部分调试,主要就是基于Chrome DevTools
的调试,所以,我们来得啰嗦的介绍一下Chrome DevTools
的功能。
现在如果你要问我怎么打开Chrome DevTools
对不起转行吧

元素模块
元素模块我们就不在细致介绍了,搞css
用的,主要功能用俩字就可以介绍------------简单
控制台模块
控制台模块也很简单,主要可以看到页面报错,console.log
打印内容 等等
有人说他不就是一个日志打印
的吗,不不不,你可不要小看控制台,他有一个非常逆天的功能
,定位问题位置

我们可以通过点击右侧链接,很清晰的定位到你源代码的位置
,以及报错位置
不过,我们能定位有一个前提,这份源代码得包含Source map
接着又有人问,啥是Source map
?
Source map
说起 Source map
如果要从头说,我可能又要开始学习另一门学问,即使我学会了,我愿意讲,各位jym
可能也不愿意听,毕竟学这玩意他也不挣钱
简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。

总是,这玩意已经被打包工具内置了,并且浏览器也支持了,我们也不用了解了,只管开发就好了 如此而已。
如果您还不痛快,请去看看阮大佬文章
当然除了以上功能,他还可以创建实时表达式,来监听dom

有什么用呢?我前面说过,他能够实时监听dom
的变化,如此一来就能窥探到vue
中数据变化驱动dom
变化中可能出现的问题
如图所示,在点击的过程中,就可以监听变化

源代码/来源模块
这个模块也是最重要的模块,因为我们可以打断点调试,能够确切的看到我们代码的执行步骤,从而迅速的定位错误

当然,这不是最重要的,debugger
么 ,谁不会啊,不就是点击,进行一步步的单步调试吗?

我们真正要看的是两点
-
1、调用堆栈
-
2、文件目录
调用堆栈
所谓调用堆栈,其实就是代码的执行脉络,对于定位问题,有着不小的功劳

透过这个脉络,我们能很快速的查看数据错误
,或者方法执行错误
文件目录
文件目录,就是左侧
的 一个目录结构

得益于Source map
的能力,在浏览器端我们能完成的还原工程目录,甚至连node_modules
都能如法炮制
通过这个目录我们就能寻根溯源
,非常方便的打断点了,就拿现在的vue2
项目为例
我么能完整的看到模板的源码,源码编译后的结果
,以及各个编译结果的引用关系
如下图所示

我们可以看到,所谓的vue模板 本质上就是一个render函数
,这也对于我们理解vue
源码有很大帮助
但是这里有一个很恶心的问题,搞过vue
项目的人都知道,虽然我们能看到编译后的函数
,但却无法下手打断点
原因很简单, render函数
的执行结果是一个vnode
,而为了得到一个个带有层级vnode
就必须有创建vnode
的函数来得的一个带有层级的vnode
不是我非得饶啊,事实他就是这么回事,我们从编译结果用也能看到端倪,他都是一个嵌套_c
函数的执行,这要打断点就会非常困难,并不能断点到准确位置
,从而看到我们想看的实时数据
不信你试试
那怎么办呢?
答案很简单,利用控制台模块
我们知道,控制台中可以用console
来打印内容,而模板中的双花括号
又可以执行函数,如此一来,简单了
我们只需要将console
放在模板中,就可以直接打印,拿到实时正确的结果,并且每次模板更新,我们也能实时更新
js
<template>
<div>
{{ log(a) }}
</div>
</template>
<script setup>
import { ref } from "vue";
const a = ref(0)
const log = (data) => {
console.log(data)
}
</script>
网络模块
网络模块咱就不过多介绍了,主要就是一些请求,属于网络协议的范畴。各位用它也就能看到请求时间,请求顺序,请求数据等等,
不能说是简单,而是非常的简单

性能模块
性能模块,原则上是没什么用的,但是我们日常开发,那就不能讲原则,因为性能优化一直是一个前端领域 的重要内容
他之所以重要,原因也很简单,你项目里可以不用,但你不可以不知道,因为一旦出现页面卡顿
、内存泄露
等问题,那就要扣钱,那时候你再知道,可就晚了
至于如何发现页面卡顿 、内存泄露 ,性能模块就很重要了

如上图所示,具体的这个图是什么意思,我就不再赘述了,很多人都讲的快吐了,我就讲一下页面卡顿
、 内存泄露
的快速调试思路
我们知道,一旦页面出现卡顿,一般有两个原因
- 1、代码执行的太猛,出现了性能瓶颈
- 2、代码执行后留下副作用,一点点堆积,导致很卡
两个原因都会导致页面卡顿,确是不同的原因导致的,我们调试的思路,应该是从内存溢出开始排查,因为这能很简单的排除另一个
排查内存溢出,也跟简单,谷歌浏览器
甚至自带任务管理器,我们通过任务管理器 能看到当前页面的内存占用,如果,在操作过程中,出现内存增加,那么恭喜你
,内存溢出了

好了,知道内存溢出
了,该怎么排查,具体是真么导致的呢
此时,性能模块 就排上用场了

因为在,性能模块中也能看到内存的占用情况,我们只需要监听页面,在操作的过程中,根据内存变化,对应下方代码执行,就能很简单的定位到具体的导致内存溢出的位置
以及代码块
而另一个页面卡顿的原因,其实就很好解决了,一般情况下,如果没有内存溢出问题,那么就是在操作执行
的过程中,代码执行太猛导致的
举个例子,频繁监听滑动事件,滚动事件,等等,那么透过性能模块,我们也能很清晰的监听到。
然后加个节流函数等等。。。
即可解决,总之就一招,就是让代码执行的不那么猛即可。。
接下来就是内存应用等模块
我们就不说了,跟调试屁关系没有,啰嗦半天,也不加工资,无聊,我们主要讲讲,vue模块
vue模块
这个模块不是Chrome DevTools
自带的,严格来说,它属于 chrome
插件,直接在商店就能下载,如果你没有梯子
那你可太无趣了,外面的世界多精彩啊
算了,看在这么爱国的情况下,告诉你吧,github
仓库也能找到,地址

vue devtools
是个很神奇的工具,能看到你想看到的一切,data数据
、 props数据
、组件嵌套层级
全部清晰可见,包裹vuex
、Pinia
的状态流转,事件操作
等等,应有尽有
甚至你不想看到的也能让你看到,比如编译后的源码

这个工具的具体使用,还请大家自己体会,我就不赘述了,因为他是在太简单了
有了以上能力,相信你的调试能力,能更上一层楼了
当然,你以为这就够了吗? 现在可是移动联网时代
,手机网页层出不穷, 移动端该怎么调试呢?
移动端真机调试
移动端的调试,其实很多人之前也讲过,无非就是什么,利用谷歌浏览器的功能等等,连接数据线,打开usb调试
云云,显得很高端
,很强悍
那么据我浅薄且真实的工作经验来看,这不是一般的扯淡,而是非同一般的扯淡,写这个的人一看就没搞过
不是说这招不行,而是很麻烦,而且也不一定能定位到问题,因为手机和电脑的表现差异很大
特别是样式差异(我曾经就被一些机器折腾的死去活来),所以这招使用价值不高,因为等你连上电脑了,别人可能都靠着笨办法调试完了
所以,我浅薄的以为,移动端调试,没什么高招,只能笨鸟先飞
当然,笨鸟虽然笨了点,可他也不傻啊,一样可以利用工具的,于是我在工作中常用的一套组合拳就出来了
charles+ vconsole
我们知道,在日常的移动端开发中,我们我们会现在谷歌端调试
,都安排好了以后,才能上真机
那么第一步布局方式选型就非常重要
关于移动端布局,我专门有个帖子讲过面试官:你了解过移动端适配吗?
有了布局以后,在移动端就成功了百分之八十了,因为他能适配大多数机型,能基本解决css 问题
那么js问题怎么解决呢?
答案就是vconsole

他是相当于是一个移动端控制台

包含内容非常丰富,足可有与pc 争锋的架势
我们页面中的一些数据打印,错误调试,都是可以用它轻松解决
当然仅仅是这样还是不够的,我们还可以利用抓包神器 charles
,因为,在日常的开发中,我们走的都是端内环境
一般页面是嵌入在app 内部的,其中的一些登录态,等等,都需要请求调试,如此一来, charles
就成了提升效率必不可少的工具

他可以修改请求,查看请求,代理请求,模拟请求等等,具体怎么使用,又变成的另一们学问,我们讲调试的,就不赘述了,jym
可以去自行搜索
但请务必学会,因为,这玩意真的很有用,并且提升效率
有可能别人数据线还没插上,你bug 都解决了
最后
祝大家调试技巧更上一层楼!!