Vue中v-show和v-if的区别

一、v-show和v-if的共同点

        若不考虑v-else,v-show和v-if的作用是一样的,都能控制元素在页面是否显示。

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

二、v-show和v-if的区别

1、控制手段不同:v-show隐藏则是为该元素添加css(display:none),dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除(将dom注释掉)。

2、编译过程不同:v-show知识简单的基于css切换;v-if在切换时将dom元素卸载,切换过程中会触发组件销毁和移除事件监听。

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

三、v-show和v-if的使用场景

  • v-if的开销更大(直接进行dom的创建与删除)
  • 如果要频繁地切换,使用v-show更好(初始开销更大,但后续切换性能较高)
  • 如果运行条件很少改变,则使用v-if更好(初始开销更小,但后续切换性能较低)

四、源码解析

v-show源码:

        有transition就执行transition,没有就直接设置display属性。

// https://github.com/vuejs/vue-next/blob/3cd30c5245da0733f9eb6f29d220f39c46518162/packages/runtime-dom/src/directives/vShow.ts
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源码

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

// https://github.com/vuejs/vue-next/blob/cdc9f336fd/packages/compiler-core/src/transforms/vIf.ts
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
          )
        }
      }
    })
  }
)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值