乐趣区

关于javascript:深入JavaScript高级语法coderwhy

download: 深刻 JavaScript 高级语法 -coderwhy

复制下崽:https://www.zxit666.com/3706/
一、v-show 和 v-if 的区别
在 vue 中 v-show 和 v-if 都能够管制元素是否在页面中事实

v-show 的显示暗藏是操作元素 css 的 display 属性,所以应用 v-show 来暗藏元素的时候,元素的 dom 节点仍旧还在页面中;v-if 的显示暗藏则是将 dom 元素整个增加或删除

v-if 的切换有一个部分编译 / 卸载的过程,切换过程中适合地销毁和重建外部的事件监听和子组件;v-show 只是简略的操作 css 的 display 属性

v-if 是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染

v-show 由 false 变为 true 的时候不会触发组件的生命周期,v-if 由 false 变为 true 的时候,触发组件的 beforeCreate、create、beforeMount、mounted 生命周期钩子,由 true 变为 false 的时候触发组件的 beforeDestory、destoryed 办法

在性能耗费方面 v-if 有更高的切换耗费;v-show 有更高的初始渲染耗费

二、v-show 和 v-if 应用场景
v-if 与 v-show 都能管制 dom 元素在页面的显示和暗藏

v-if 相比 v-show 开销更大的(间接操作 dom 节点减少与删除),如果须要十分频繁地切换,则应用 v-show 较好,如果在运行时条件很少扭转,则应用 v-if 较好

三、v-show 和 v-if 原理剖析
v-show 不论是 true 还是 false,元素总是会被渲染,源码中如果绑定了 v-show 指令的元素外层套了一层 transition 的话,就执行 transition,如果 el 外层没有嵌套 transition 的话,就间接设置 el.style.display

export const vShow: ObjectDirective<VShowElement> = {
beforeMount(el, { value}, {transition}) {

el._vod = el.style.display === 'none' ? '' : el.style.display
if (transition && value) {transition.beforeEnter(el)
} else {setDisplay(el, value)
}

},
mounted(el, { value}, {transition}) {

if (transition && value) {transition.enter(el)
}

},
updated(el, { value, oldValue}, {transition}) {

// ...

},
beforeUnmount(el, { value}) {

setDisplay(el, value)

}
}

复制代码
v-if 是在形象语法树转成代码字符串的时候被获取来做判断的,如果 v-if 为 false,render 函数生成的 vnode 不会蕴含要渲染的节点,而是一个正文的 vnode 节点作为占位
export const transformIf = createStructuralDirectiveTransform(
/^(if|else|else-if)$/,
(node, dir, context) => {

return processIf(node, dir, context, (ifNode, branch, isRoot) => {
  // ...
  return () => {if (isRoot) {
      ifNode.codegenNode = createCodegenNodeForBranch(
        branch,
        key,
        context
      ) as IfConditionalExpression
    } else {
      // attach this branch's codegen node to the v-if root.
      const parentCondition = getParentCondition(ifNode.codegenNode!)
      parentCondition.alternate = createCodegenNodeForBranch(
        branch,
        key + ifNode.branches.length - 1,
        context
      )
    }
  }
})

}
)

退出移动版