v-if和v-show的区别及源码分析

简介: v-if和v-show的区别及源码分析

一.v-if和v-show的原理

  • v-if:通过移除元素来实现元素的显示与隐藏,每次显示都会触发组件的mouted钩子函数。可以用来表面意义上的刷新组件
  • v-show:通过设置元素的display属性来控制元素的显示与隐藏。elementui的弹窗组件就是利用v-show来控制显示与隐藏的。

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

  1. 加载速度不同,v-show要比v-if快,实际项目中就是这样。
  2. 原理不同。
  3. 应用场景不同,v-if多用于需要刷新的组件。v-show多用于不需要刷新组件的显示与隐藏。
  4. 组件内缓存子组件就是用的v-show。就是用的v-show。
  5. 做项目优化的时候可以尽量使用v-show,具体看需求。

    三.vue源码分析v-if和v-show

    在开始之前我们要知道vue2中字符串模板解析编译成真实DOM的过程,大致流程如下:
    1.将模板template转为ast结构的JS对象
    2.用ast得到的JS对象拼装render和staticRenderFns函数
    3.render和staticRenderFns函数被调用后生成虚拟VNODE节点,该节点包含创建DOM节点所需信息
    4.vm.patch函数通过虚拟DOM算法利用VNODE节点创建真实DOM节点
    v-if源码分析
    1.在模板编译的parse阶段,会使用 processIfConditions 函数处理条件渲染:
    function processIfConditions (el, parent) {
         
    const prev = findPrevElement(parent.children)
    if (prev && prev.if) {
         
     addIfCondition(prev, {
         
       exp: el.elseif,
       block: el
     })
    } else if (process.env.NODE_ENV !== 'production') {
         
     // 警告信息
    }
    }
    

2.在模板编译的 codegen 阶段,会调用 genIf 函数处理 v-if 所在的标签:

export function genIf (
  el: any,
  state: CodegenState,
  altGen?: Function,
  altEmpty?: string
): string {
   
  el.ifProcessed = true // avoid recursion
  return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
}
function genIfConditions (
  conditions: ASTIfConditions,
  state: CodegenState,
  altGen?: Function,
  altEmpty?: string
): string {
   
if (!conditions.length) {
   
    return altEmpty || '_e()'
  }
  const condition = conditions.shift()
  if (condition.exp) {
   
    return `(${condition.exp})?${
      genTernaryExp(condition.block)
    }:${
     
      genIfConditions(conditions, state, altGen, altEmpty)
    }`
  } else {
   
    return `${
     genTernaryExp(condition.block)}`
  }
  // v-if with v-once should generate code like (a)?_m(0):_m(1)
  function genTernaryExp (el) {
   
    return altGen
      ? altGen(el, state)
      : el.once
        ? genOnce(el, state)
        : genElement(el, state)
  }
}

从代码中可以看出,v-if 指令会转化成三目运算符的形式

带有 v-if 指令的模板会编译成根据数据源真假值来调用具体辅助方法的渲染函数,v-if 会根据数据源真假值来决定是否渲染该节点,这一点与 v-show 不同。
v-show源码分析
在调用处理指令的钩子函数 updateDirectives 时,v-show 指令有所不同,相当于 v-show 内部实现了自定义指令的 bind、update、unbind 三个阶段的钩子函数。

export default {
   
  bind (el, {
    value }, vnode) {
   
    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'
    }
  },
 update (el, {
    value, oldValue }, vnode) {
   
    if (!value === !oldValue) return
    vnode = locateNode(vnode)
    const transition = vnode.data && vnode.data.transition
    if (transition) {
   
      vnode.data.show = true
      if (value) {
   
        enter(vnode, () => {
   
          el.style.display = el.__vOriginalDisplay
        })
      } else {
   
        leave(vnode, () => {
   
          el.style.display = 'none'
        })
      }
    } else {
   
      el.style.display = value ? el.__vOriginalDisplay : 'none'
    }
  },
  unbind (el,binding,vnode,oldVnode,isDestroy){
   
    if (!isDestroy) {
   
      el.style.display = el.__vOriginalDisplay
    }
  }
}

从上述代码可以看到,v-show 指令仅仅是通过调用 DOM.style.display 的值来显示和隐藏DOM元素。

相关文章
|
存储 前端开发 对象存储
一文搞懂Map与Set的用法和区别!
前言 作为前端开发人员,我们最常用的一些数据结构就是 Object、Array 之类的,毕竟它们使用起来非常的方便。往往有些刚入门的同学都会忽视 Set 和 Map 这两种数据结构的存在,因为能用 set 和 map 实现的,基本上也可以使用对象或数组实现,而且还更简单。 但是,存在必然合理,当你真正了解 Map 和 Set 之后,你就会发现它们原来时如此美好!
2099 0
一文搞懂Map与Set的用法和区别!
|
6月前
|
前端开发 JavaScript
v-if和v-show的区别
v-if和v-show的区别
39 0
|
6月前
|
移动开发 安全 数据安全/隐私保护
class dump使用方式和原理
class dump使用方式和原理
39 0
|
11月前
|
移动开发 安全 数据安全/隐私保护
class dump使用方式和原理
导出的包是经过混淆,经过加固比较安全的包了
|
JavaScript 算法 前端开发
v-show和v-if有什么区别?使用场景分别是什么?
v-show和v-if有什么区别?使用场景分别是什么?
121 0
|
JavaScript
v-show和v-for区别
v-show和v-for区别
v-show和v-for区别
|
JavaScript 前端开发
v-show和v-if的区别(面试题)
v-show和v-if的区别(面试题)
57 0
|
JavaScript 前端开发
v-show和v-if区别
v-show和v-if区别
126 0
|
JavaScript 前端开发
v-if和v-show的区别?
v-if和v-show都是Vue.js框架中的指令,用于根据条件显示或隐藏DOM元素,但它们的实现方式不同,导致在使用时需要注意以下区别: