1、手动挂载的隐患
vue组件内,我们有时候会通过js,手动挂载一些其他节点:
但这会出现一个什么问题呢,就是当通过修改vue组件模板依赖的属性,或通过调用 $forceUpdate 方法的时候,也即是vue组件重新渲染的时候,会将手动挂载的dom覆盖:
又恢复到了未挂载的状态。
2、问题的出现与排查
2.1、问题的出现
客户反馈分类这块区域有时候会出现空白的情况:
通过反复的刷新,发现具体情况是:
先空白(还未初始化)-> 出现数据(首次渲染)-> 重新空白(未知原因)
但通过打断点发现,渲染的方法确实进入过,且dom、数据都是有的,并没有什么异常:
而且通过 mounted 钩子确定组件并没有反复挂载的情况。而且即便有,也会在组件挂载后,走手动挂载dom的逻辑的。
2.2、问题的定位
通过排查发现,重新空白的dom结构,跟原始的、未手动挂载的dom结构一致:
故怀疑是反复执行 render 函数的原因。
通过打断点发现,render函数确实被调用了几次:
而问题的原因就是本文第一点提到的,因为触发了重新渲染,导致手动挂载的dom被覆盖掉了。
3、解决方案
因为这是vue触发dom刷新导致的,所以我们可以利用 updated 钩子( 通过调用 $forceUpdate 方法触发的刷新也会执行这个钩子)。
把原先只在 mounted 钩子内执行的手动挂载 dom 的逻辑,也添加到 updated 钩子执行。
但要注意的是,并非所有的刷新都需要触发重新挂载,所以 updated 钩子的函数需要另外做些限制: