浅析v-if与v-show的区别
2024-12-09 11:13:16
典中典的面试题,属于我刚入门的时候在问,到现在几年了,还在问。
这么多年了,面试官真是一点进步都没有。
正文
无论是vue3还是vue2,关于这些个简单的vue指令变动都是不大的,这里就直接以v3的源码为例子,看看这块到底怎么个事儿。
源码浅析
vue的大致渲染流程如下,这里不详细展开说,改天开单章细说。
- 将模板
template
转为ast
结构的JS
对象 - 用
ast
得到的JS
对象拼装render
和staticRenderFns
函数 render
和staticRenderFns
函数被调用后生成虚拟VNODE
节点,该节点包含创建DOM
节点所需信息vm.patch
函数通过虚拟DOM
算法利用VNODE
节点创建真实DOM
节点
v-show原理
不管初始条件是什么,元素总是会被渲染。
这里我们看一下在vue
源码是如何实现的。
代码很好理解,有transition
就执行transition
,没有就直接设置display
属性
这里我们也看到了,v-show只是执行了挂载和更新的相关周期,所以并非是全生命周期的方法。。
1 | // https://github.com/vuejs/vue-next/blob/3cd30c5245da0733f9eb6f29d220f39c46518162/packages/runtime-dom/src/directives/vShow.ts |
v-if原理
v-if
在实现上比v-show
要复杂的多,因为还有else
else-if
等条件需要处理,这里我们也只摘抄源码中处理 v-if
的一小部分
返回一个node
节点,render
函数通过表达式的值来决定是否生成DOM
1 | // https://github.com/vuejs/vue-next/blob/cdc9f336fd/packages/compiler-core/src/transforms/vIf.ts |
面试回答
以下算是教科书的回答,个人觉得很经典,可以考虑再搭配一点场景来辅助记忆。
虽然 v-if
和 v-show
都可以用于根据条件展示元素,但它们背后的实现机制和适用场景有所不同。
当然,面试时候最好不要回答源码相关,除非你对源码有极深的理解,不然面试官会以为你对源码研究颇深,甚至以为你对源码有贡献。
一旦问题脱缰,装到了面试官擅长的领域,到时候容易控不住场,所以,要适度装逼。
- 渲染机制:
v-if
是条件性地渲染元素,即如果条件不满足,元素甚至不会被添加到 DOM 中;而v-show
元素无论条件如何始终会被渲染到 DOM 中,只是通过切换display
属性来控制显示。 - 性能考虑:因为
v-if
控制的元素不会被频繁切换或者在初始化时条件就不成立,使用v-if
更为合适,避免了不必要的渲染成本。而v-show
适用于需要频繁切换显示状态的场景,因为元素始终保持在 DOM 中,切换开销更小。 - 编译过程:
v-if
是真正的条件渲染,因为它确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。而v-show
只是简单地切换元素的display
CSS 属性。 - 使用场景:当你的条件很少改变时,推荐使用
v-if
;如果需要非常频繁地切换,使用v-show
会更好,但是实际开发过程中,大多数业务场景不缺这点性能,这种场景我们很难见到。
个人拓展
但是,实际开发过程中,大多数使用v-if来做处理问题。
- v-if因为将元素完成了移除,这样能够较为完全的注销子组件,这样,子组件内的生命周期是从created触发的,如果子组件中有什么方法一定要写在created中,那么这里就非常推荐使用v-if了。
- v-show无法配合v-else做条件渲染,如果有多个条件渲染,v-if显然比v-show的适用面更广一些。
- template支持v-if,但却不支持v-show,有些时候,可以使用template配合v-if来写组件切换的效果,有些组件库中也有很多template打头的插槽,这里推荐使用v-if来写,而不是v-show。
结语
v-show与v-if的区别,新手都知道的问题,但是将这种简单的问题回答的出彩,也很重要。