总结记录最近开发中遇到的两个BUG
前一段时间在日常开发时,遇到两个问题,当时虽然解决了但没有总结,今天沉淀文档里总结一下。
调试时debugger和断点不生效
这个问题刚遇到时,觉得很奇怪啊。
明明什么都没动过,以往可以正常有断点的地方却突然有一天好像断点失效了。
不可能是chrome的问题,项目重启也没用,临时采取console.log
方式调试代码凑合着。
不忙的时候查阅了一些资料发现还真有人遇到过,大概有以下两个解决方案:
方案一:在开发者工具devtool上设置
谷歌浏览器-打开开发者工具-设置-Ignore List -取消勾选 /node_modules/bower_components即可 操作步骤如下:
- 打开开发者工具(能看到这的应该都知道,这里再啰嗦一下)
直接按一次键盘上
F12
键或者Ctrl + Shift + I
或者如图
- 打开开发者工具里设置选项
-
忽略列表选项里,去掉勾选 自定义排除规则
-
取消勾选之后再次运行
**方案二:在 vue.config.js
文件增加 devtool:"source-map"
配置 **
- 如图在
vue.config.js
文件中增加devtool:"source-map"
配置,如图:
- 添加之后重启项目
npm run dev
即可
Vue项目中bus.$emit
触发自定义事件,bus.$on
却监听不到
Vue中使用bus.$emit
触发自定义事件,但是有时在另一个组件中使用bus.$on
却监听不到。
和这位大佬遇到的问题几乎是一模一样的,他这里是因为不同的弹框组件切换显示、隐藏时,在组件beforeDestroy
生命周期手动取消了bus
事件。
我的也是多个不同的组件切换显示、隐藏时,在组件beforeDestroy
生命周期手动取消了bus
事件。
用了大佬的解决方法果然好使。
BUG情况:页面顶部区域搜索条件发现变化时,会触发bus.$emit('seachData', params)
事件,compA、compB、compC
是三个tab页的按钮,依次对应三个页面pageA、pageB、pageC
。
初始时,tab compA
是active
状态,此时显示pageA
页面,搜索条件发现变化,触发bus.$emit('seachData', params)
事件,在pageA
页面可以通过bus.$on('searchData', (params) => {})
监听到,后续根据新的搜索条件更新pageA
页面的数据。此时在pageA
页面确实可以监听到bus.$emit('seachData', params)
事件。
接着,切换tab
到compB
,此时显示pageB
页面,搜索条件再次发现变化,虽然通过联调手段证实触发了bus.$emit('seachData', params)
事件,但是在pageB
页面通过bus.$on('searchData', (params) => {})
监听,就是监听不到bus.$emit('seachData', params)
事件。
具体解决的过程是这样的:
在单个模块里使用,不会有什么问题,但是如果从compA
切换到compB
之后,就就监听不到了。然后我在那个搜索条件文件中console.log
了一下,发现该文件确确实实使用bus发出了一个自定义事件bus.$emit('seachData', params)
。然后发现是切换之后,从compA
切换到compB
之后,bus
都接收不到该事件。
问题解决1:
bus.$on
监听不到事件,我首先想到的是因为我的代码中$emit()
事件先于$on()
监听事件执行了,Vue
中并没有储存监听事件,所以无法监听到数据。即:用总线方式实现兄弟组件间的传值时,必须保证$on()
监听事件先被创建,否则无法正常监听消息。
为了验证是否是这个原因,我使用nextTick
或setTimeout
,保证每个组件里的$on()
监听事件都在$emit
触发之前,发现没有用,切换组件之后还是监听不到。
问题解决2:
既然$on()
都在$emit
之前,那么单个文件来看,肯定都没有问题。
接着将两个模块的文件一起看。然后发现:为了不增加内存,在每个模块的beforeDestroy
生命周期函数里面,我都会去释放这个事件this.bus.$off('seachData')
,问题就出在这里了。
表面上看确实没有任何问题,因为这是正常操作,bus
监听之后,在离开之后再取消监听。但是切换时,被deactive
的那个组件会走beforeDestroy
生命周期函数,会把监听事件取消掉,这样在active
的组件里就没法$on()
这个事件了。
注:旧组件、新组件切换时,对应的生命周期执行顺序:新组件
created
(执行$on('seachData')
) -> 旧组件beforeDestroy
(取消$off('seachData')
) -> 新组件mounted
。
本打算把所有组件里beforeDestroy
生命周期bus.$off('seachData')
这一步注释掉,但是这样组件切换多次时,会$on
多次;只要不刷新页面,组件切换次数越多,$on
监听的次数越多,最后系统奔溃,是非常不可取的。
最终:
我把每个模块bus.$off('seachData')
事件的操作,放在beforeRouteLeave
的生命周期钩子函数中,这样在模块切换的过程中,就不会对后面这个新组件模块的bus
监听产生影响了。