前端答疑 - v-if 从新渲染致使的 Bug

由于疫情五一假期也不能出去玩,只好在家撸代码。html

正好昨天排查了一个问题,今天记录一下。前端

问题

问题是这样的,有个页面它里面有两个组件 1活动组件、2搜索组件,而后活动组件里面有个评论留言的功能,测试同窗发现组件切换以后评论被清空了
问题大致就这样。由于活动不是我作的,我只负责排查问题,因此我也是听别人的反馈来分析问题。vue

页面

感兴趣的朋友能够实际下载APP去看一下,VV音乐-首页轮播图-五一假期与美同行
以下,切换以后 UI 还在,只是记录数和评论没了面试

image.png

基础条件分析

  1. 单页面组件切换(不涉及到路由、或者页面通讯乱七八糟的场景)
  2. 不存在页面被异常刷新状况(由于刷新就等于从新打开,从新打开是没有问题的。)
  3. 评论是公用的一个 js 实现,不是基于 Vue 的。(重点来了缓存

    1. vue 讲究的是数据驱动视图,只要数据在,视图就ok
    2. js、jQuery 讲究的是 DOM,想插节点插节点,节点没了就没了。

常见问题排查

到这里问题已经比较清晰了,Vue 如何使用原生库。通常来讲遇到的问题分为下面几个。服务器

  1. 获取不到 DOM 节点。这里通常是 nextTick 的问题,由于你操做完数据以后,他并无渲染完毕呢。
  2. 组件开发中获取 DOM 不方便,有可能出现重复。这里咱们能够用 ref 来获取。
  3. 排序拖动等功能不生效。通常是看上去变了,可是数据不对。由于 jQuery库的理念就是 DOM 对了就是对了,可是在 Vue 中必需要数据对了,而后数据渲染到页面。因此处理方式通常是放弃修改 DOM,改成修改数据。

这个 Bug 还比较特殊,不是这里面的,可是也有关系(和 3 的问题相似)。接来下出道面试题吧微信

v-if 和 v-show 的区别

这面试题不陌生吧,想必你们也有答案。函数

v-if

v-if 根据表达式的值的来有条件地渲染元素。采用组件销毁、重建的方式。测试

若是一开始就是 false,那么这个组件不会被建立(生命周期钩子函数不会被调用)。spa

若是一开始是 true,而后改成 false,这个时候组件会被销毁(destory 等生命周期钩子函数都会执行)。以后若是再改成 true,那么会从新建立(created 等钩子函数会执行)。

v-show

v-show 根据表达式的值的来有条件地渲染元素。是经过设置元素的 display CSS 属性来实现渲染效果。

无论是 true 仍是 false 都会渲染出组件。只不过为 falsedisplay:none

解决问题

基于上面的分析咱们知道了,由于 v-if 致使组件被销毁,而后再次渲染的时候是根据 Vue 中的数据来渲染的,并无 DOM 数据。

解决方案一:v-show

既然 v-show 不会销毁,那么咱们能够缓存 v-show

这个方案的缺点

  1. 组件在一开始初始化的时候就所有被渲染了。会存在大量请求、无效数据打倒服务器。
  2. 由于他在一开始就渲染了,因此若是你没有加载完数据的话,存在报错的可能性。list && list.length 少不了这种代码的存在

解决方案二:切换以后再调用一次

既然 created 的时候是好的,那么咱们切换以后再次调用一下初始化渲染不就能够了。

这个方案的缺点

  1. 由于存在二次渲染,jQuery 等插件通常都会监听事件。因此须要注意事件不能被屡次触发。
  2. 仍是由于上个问题,也要注意由于事件引用等问题致使的内存泄漏。

测试DEMO

https://www.lilnong.top/stati...

补一下 DEMO,能够看到一进去四个 input 都是有内容的。

切换以后 v-if 下面的input就有个丢值了。而 v-show 的不受影响。

增长 keep-alive 和组件测试

能够先在 keep-alive 组件中填入内容,而后切换,发现 v-if 的数据没有了
image.png

微信公众号:前端linong

欢迎你们关注个人公众号。有疑问也能够加个人微信前端交流群。
clipboard.png

相关文章
相关标签/搜索