vue相关知识整理-v-if和v-show

1,310 阅读4分钟

src=http___static001.infoq.cn_resource_image_c4_01_c4251ee38c2039602d69cac1d3ab9d01.jpg&refer=http___static001.infoq.jpeg

vue基础知识整理

为了回避错误、小纠结和反模式,整理一份文档进行参考,不定期更新内容,作为工作查找和基础知识积累的记录。

1.v-if 和 v-show 区分使用场景

v-if

是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

需要注意以下几点:

  • 某一块代码在运行时条件很少改变,使用v-if较好 (v-if 有更高的切换开销)
  • key结合使用, 管理可复用的元素(Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染)
  • template配合使用,可以分组渲染代码块
  • v-else或者v-else-if结合使用
  • 在组件上使用v-if可触发组件的生命周期函数
  • v-for 结合使用时,v-forv-if 的优先级更高
  • transition结合使用 当条件变化时该指令可以触发过渡效果(用于动画切换)
  • keep-alive结合使用可保留组件状态,避免重新渲染

v-show

会渲染dom,根据v-show的值进行显示和隐藏处理,如果当前元素存在频繁切换的操作,建议用v-show实现。

需要注意以下几点:

  • 需要非常频繁地切换某块代码,使用v-show渲染
  • 当条件变化时该指令触发过渡效果(用于动画切换)
  • 不可用于组件
  • 没有条件语句

两者共同点

  • 当两者都为false时,都不会占据页面位置(v-if是删除dom,v-show是切换dispaly的状态)
  • 当条件变化时都会触发过渡效果(用于动画切换)

原理分析

我们知道vue的渲染逻辑,首先我们需要先把模板转换成js代码,也就是把模板中的v-ifv-forv-modal等进行事件监听,转换成可执行的js代码(也就是render函数),因为js有逻辑是一种图灵完备的语言。然后执行render函数处理模板转换成html。而在这个过程中v-ifv-show就会被解析。

v-if 就像if()else()一样动态的区创建元素,注意在这个过程中如果v-if控制的是组件,切换过程中条件块内的事件监听器和子组件会被适当地销毁和重建,也就是会触组件和子组件的生命周期。

简单来说其实就是如果元素中有v-if的话,就将v-if的条件取出来加入到el.ifConditions里面,如果有 v-elsev-else-if属性的话就将相应的标志位置为成true。当遇到当前elev-else或者v-elseif属性的时候,需要处理if属性,在其上级兄弟元素中必然存在v-if属性,然后将当前元素的else-if上表达式添加到上个元素的ifConditions上。然后生成AST树,当AST树生成完成后,接下来要根据刚刚挂载这颗树上的相应属性。来生成相应的render函数了。最后在执行render函数时,会根据vue中绑定变量的值,来决定创建哪一部分的template

v-show的实现原理可以看下图:

image.png

  • 首先,由 widthDirectives 来生成最终的 VNode。它会给 VNode 上绑定 dir 属性,即 vShow 定义的在生命周期中对元素 CSS display 属性的处理
  • 其次,在 patchElement 的阶段,会注册 postRenderEffect 事件,用于调用 vShow 定义的 update 生命周期处理 CSS display 属性的逻辑
  • 最后,在派发更新的结束,调用 postRenderEffect 事件,即执行 vShow 定义的 update 生命周期,更改元素的 CSS display 属性

小结

弄懂原理以后其实就明白了 为什么 v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。学习源码是一个枯燥的过程,但是如果能够坚持,一定就会有收获。

注意

官方文档提出了一些注意事项一定要牢记官方文档风格指南