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-for
比v-if
的优先级更高 - 与
transition
结合使用 当条件变化时该指令可以触发过渡效果(用于动画切换) - 与
keep-alive
结合使用可保留组件状态,避免重新渲染
v-show
会渲染dom,根据v-show
的值进行显示和隐藏处理,如果当前元素存在频繁切换的操作,建议用v-show
实现。
需要注意以下几点:
- 需要非常频繁地切换某块代码,使用
v-show
渲染 - 当条件变化时该指令触发过渡效果(用于动画切换)
- 不可用于组件
- 没有条件语句
两者共同点
- 当两者都为
false
时,都不会占据页面位置(v-if
是删除dom,v-show
是切换dispaly的状态) - 当条件变化时都会触发过渡效果(用于动画切换)
原理分析
我们知道vue的渲染逻辑,首先我们需要先把模板转换成js代码,也就是把模板中的v-if
,v-for
,v-modal
等进行事件监听,转换成可执行的js代码(也就是render
函数),因为js有逻辑是一种图灵完备的语言。然后执行render
函数处理模板转换成html
。而在这个过程中v-if
和v-show
就会被解析。
v-if
就像if()else()
一样动态的区创建元素,注意在这个过程中如果v-if
控制的是组件,切换过程中条件块内的事件监听器和子组件会被适当地销毁和重建,也就是会触组件和子组件的生命周期。
简单来说其实就是如果元素中有v-if
的话,就将v-if
的条件取出来加入到el.ifConditions
里面,如果有 v-else
,v-else-if
属性的话就将相应的标志位置为成true
。当遇到当前ele
有v-else
或者v-elseif
属性的时候,需要处理if属性,在其上级兄弟元素中必然存在v-if
属性,然后将当前元素的else-if上表达式添加到上个元素的ifConditions
上。然后生成AST树
,当AST树
生成完成后,接下来要根据刚刚挂载这颗树上的相应属性。来生成相应的render
函数了。最后在执行render函数时,会根据vue中绑定变量的值,来决定创建哪一部分的template
。
v-show的实现原理可以看下图:
- 首先,由
widthDirectives
来生成最终的VNode
。它会给VNode
上绑定dir
属性,即vShow
定义的在生命周期中对元素CSS display
属性的处理 - 其次,在
patchElement
的阶段,会注册postRenderEffect
事件,用于调用vShow
定义的update
生命周期处理CSS display
属性的逻辑 - 最后,在派发更新的结束,调用
postRenderEffect
事件,即执行vShow
定义的update
生命周期,更改元素的CSS display
属性
小结
弄懂原理以后其实就明白了 为什么 v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。学习源码是一个枯燥的过程,但是如果能够坚持,一定就会有收获。
注意
官方文档提出了一些注意事项一定要牢记官方文档风格指南