Vue中动态class覆盖原生class的问题
这一个小伙伴发来的bug
现在的问题是
这个下拉的菜单有时候关不上
现在是正常
但是呢当我切换一个界面
我们再回来
大概就关不掉了
点击空白处也不好使
只能去点击上面这个菜单
碰到这种问题呢
我们首先肯定是想到去看一下
他代码的逻辑
是怎么写的
但是呢我去看了一圈竟然发现
他连一个click事件都没有写
大家看
只是呢我发现他有一个这样的属性
还有这个
后来我搜了一下哈
这个啊就是bootstrap的一个属性
所以就意味着它现在啊
这个展开和收起的效果
都是由bootstrap来管理的
所以刚开始看到这呢线索一下就断了
就无从下手了
后来呢我就想了个办法
既然他正常的情况下
可以点击空白处去收起
说明他肯定有
点击事件放在全局了
所以呢我们可以这样选中body
然后在这选event list
然后展开click
大家看有这么多click
然后呢我们先把它展开
我们就一个一个的移除
看看把哪个移除掉之后
他这个点击空白处他就不好使了
比如说我随便移除一个
大家看它还能关闭
我再把它打开
我就移除第一个
大家看这回就没有了
说明啊刚才我移除的那个第一个
就是来管理这个菜单关闭的
我们再刷新一下 (目的是把移除的第一个事件还原回来)
好然后我们把它打开
我们直接点进去第一个
点进去之后呢
我发现它是一个公用的时间绑定的
那我们就在这apply上面打个断点
然后点空白处
走到这之后呢
把断点关掉
单步跳入
我们看走到哪个方法里
然后呢
我们来看一下他这个方法是怎么走的
注意走到这之后呢
他有一个循环
注意他现在循环的这个数组啊open togens
是有直的大家看
然后呢后边我们先不看了哈
我们直接放行
我们把这个
bug复现出来
先点别的地方
然后再回来
好现在就关不掉了对吧
然后我们还是在这打断点
我们再点一下空白处
大家看这个open tons就没有数据了
这个数据
所以他就不会走里边了
所以呢现在就有一点线索了
在有bug的情况下
这个变量是没有数据的
那为什么他没有数据呢
我们重新来走一下这个代码
我们现在放行一下
看在这为什么没找到对吧
大家看走到这了我们单步跳入
走进去之后呢
我们会发现其实他就是在调query selector
我们右键啊把它复制出来copy string contents
然后我们在控制台自己写一个
document.querySelectorAll
然后呢把刚才这个selector拿过来
大概是没有的
那我们再把它的范围扩大一点
我们去掉一些选择
只留一个这个大概就有了
然后呢再加上一些
我就只去掉show吧
大家看 就有了
加上show呢
就没了
也就是说在关不掉的情况下
应该有这么一个元素是有.show的
但是它没有了
哪个元素呢
我们来看这个a标签
大家看正常是没有展开的时候没有
但是我们把它展开的时候呢
它是有一个show 的样式的
这个样式其实就是bootstrap
直接来操作到我们节点来放上去的
比如说当我们展开的时候呢
bootstrap会给这个a标签加一个show
然后点空白的地方呢
它会通过这个.show(配合其他selector拼接)来找到这个a标签
然后去进行关闭操作
但是呢当我们切换页面的时候
注意啊我们切换再回来
大家看现在这个菜单是打开的
但是这个show已经没了
那为什么会这样呢
看到这啊
对vue比较熟的小伙伴可能会猜到
它这个a标签啊有一个动态的class
这里边的条件如果发生变化了
will就会把整个这个
class列表重新渲染
我们来看这个例子
这个例子里面就一个span标签
然后一个切换样式的按钮
代码呢也很简单就是这样
一个span标签
然后呢它有一个静态的样式
还有一个动态的样式
这个动态呢就是一个true和false
然后通过这个按钮来切换它的true/false
我们来看一下啊
现在呢它只有一个static
然后点按钮再看多了一个动态
再点呢动态就没了对吧
然后注意我在这手动加一个样式叫red
大家看它就有红色背景了
但是呢
这个时候我再点按钮切换的时候
注意这个red就丢了
大家看
原因就是啊
我们直接操作到dom节点
加的这个样式
没有被vue记录下来
所以当他再次重新渲染的时候呢
这个red样式就丢了
回到这个呢他也是这样的
所以呢解决这个小伙伴的bug呀
我研究了一下有两个方案
第一个方案就比较快
就是我们呀
无论如何都给他加一个.show
我看了一下
bootstrap没有对这个(.nav-link的).show
进行页面样式的声明
也就是说:这个show
只是用于js层面的一个判断(标识)
它没有任何样式的声明
所以呢我们给它加上也不会影响样式
大家看我们再来试一下
可以收起
切换回来也没有问题了
因为回来的时候默认他有个show
然后呢bootstrap就可以
找到这个元素顺利的把它关掉了
这是第一种方案
第二种方案呢就是啊
我看了一下他用的这个bootstrap啊
就是原声的这个Boosttrap
其实呢Boostrap是有vue版的Boostrap的
所以呢最理想的是啊
我们采用vue版的bootstrap
然后呢他想用的什么组件
包括这个下拉的组件这里边他都有
Dropdown
它叫b-dropdown
所以呢
如果我们采用这个vue版的bootstrap
我相信这个问题也能得到解决
而且呢应该说会解决的更彻底
最后更新于
这有帮助吗?