Vue-源码解析v-if 和 v-show

1、共同点

皆可动态控制DOM元素的显示与隐藏

2、区别

v-if

  • 动态的向DOM树内添加或者删除DOM元素
  • 真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;在初始渲染条件为假时,什么也不做。
  • 由于存在销毁和重建,具有更高的切换消耗

v-show

  • 通过设置DOM元素的display样式属性控制显示和隐藏
  • 不管初始条件是什么,元素总是会被渲染,只是简单地基于 CSS 进行切换。
  • 由于总是会被渲染,所以初始时有更高的渲染消耗

3、原理剖析

v-if

const VueTemplateCompiler = require('vue-template-compiler')

const template = '<div v-if="true"><span>hello world</span></div>'

// 模版编译成render方法
const compile = VueTemplateCompiler.compile(template)

console.log(compile.render)

// 结果
with (this) { return (true) ? _c('div', [_c('span', [_v("hello world")])]) : _e() }

满足条件时会创建DOM元素,不满足时会通过_e创建空节点,在vue/src/core/instance/render-helpers/index.js可以看到_e方法的定义target._e = createEmptyVNode

v-show

const VueTemplateCompiler = require('vue-template-compiler')

const template = '<div v-show="true"><span>hello world</span></div>'

// 模版编译成render方法
const compile = VueTemplateCompiler.compile(template)

console.log(compile.render)

// 结果:true
with (this) { return _c('div', { directives: [{ name: "show", rawName: "v-show", value: (true), expression: "true" }] }, [_c('span', [_v("hello world")])]) }
// 结果:false
with (this) { return _c('div', { directives: [{ name: "show", rawName: "v-show", value: (false), expression: "false" }] }, [_c('span', [_v("hello world")])]) }

编译出v-show的指令其他并没有特殊处理,然后我们去看看v-show到底做了什么,找到vue/src/platforms/web/runtime/directives/show.js,会发现以下核心代码

bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) {
    vnode = locateNode(vnode)
    const transition = vnode.data && vnode.data.transition
    const originalDisplay = el.__vOriginalDisplay =
      el.style.display === 'none' ? '' : el.style.display
    if (value && transition) {
      vnode.data.show = true
      enter(vnode, () => {
        el.style.display = originalDisplay
      })
    } else {
      el.style.display = value ? originalDisplay : 'none'
    }
  },

从代码里可以看出v-show是通过改变CSS style.display来操作元素的显示与隐藏

4、应用场景

v-if

适合运行条件很少改变的情况,例如涉及到根据用户权限(不常变化)动态显示菜单,

v-show
适合频繁切换的情况,例如tab切换时子模块变化情景,且会保留用户之前的操作状态

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值