likes
comments
collection

vue中v-show和v-if深入理解

作者站长头像
站长
· 阅读数 19

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

很常见的一个问题,v-show和v-if有什么区别?

看一波源码

v-show原理

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)
  }
}

transition就执行transition,没有transition就直接设置display。不管初始条件是什么,元素总是会被渲染。

v-if原理

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
          )
        }
      }
    })
  }
)

返回一个node节点,render函数通过表达式的值来决定是否生成DOM

相同点

都能控住元素在页面上是否显示

<div v-show="isShow"></div>
<div v-if="isShow"></div>

不同点

  • 控制手段不同:v-show是控制css的display是否为none来隐藏或展示,dom元素一直都是在的。而v-if显示隐藏是直接将整个dom元素添加或删除。
  • 编译过程不同:v-show只是简单地基于css切换。而v-if的切换有一个局部编译/卸载的过程,切换过程中会销毁和重建内部的事件监听和子组件。
  • 编译条件不同:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件被销毁和重建,只有渲染条件为真时才渲染。
  • v-show由false变为true的时候不会触发组件的生命周期。
  • v-if由false变为true的时候,触发组件的beforeCreatecreatebeforeMountmounted钩子,由true变为false时触发组件的beforeDestorydestoryed方法。
  • v-if有更高的切换消耗,v-show有更高的初始渲染消耗。

使用场景

  1. 如果需要频繁地切换,则v-show较好。
  2. 如果在运行时条件很少改变,则使用v-if较好。