0x01Vue面试题-说说v-if(v-show/v-for)

v-if/v-show/v-for
v-if/v-show/v-for

v-if有关的面试题目:

  1. Vue中的v-show和v-if怎么理解?
  2. 为什么Vue中的v-if和v-for不建议一起用?

一、 Vue中的v-show鱼v-if怎么理解?

0x00:相同点:
作用效果相同的,能够控制元素在页面是否显示

0x01: 区别:

控制手段:
v-show:通过css-display:none, dom元素依旧存在
v-if: 将dom元素添加或者删除

编译过程:
v-show: 简单的基于css切换
v-if:切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

编译条件:
v-if: 是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染
v-show: 由false变为true的时候不会触发组件的生命周期
v-if: 由false变为true的时候,组件创建生命周期,由true变为false的时候触发组件销魂周期

性能消耗:
v-if有更高的切换消耗;
v-show有更高的初始渲染消耗;

概括: v-if:控制dom是否存在[创建和销魂]来控制隐藏,所以在切换的时候消耗资源 v-show: 通过css样式控制是否显示,元素一直存在的,初始化的时候创建。

0x02: 原理:

1)v-show 源码:控制style.display的css样式

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 }) {
    if (!value === !oldValue) return
    if (transition) {
      if (value) {
        transition.beforeEnter(el)
        setDisplay(el, true)
        transition.enter(el)
      } else {
        transition.leave(el, () => {
          setDisplay(el, false)
        })
      }
    } else {
      setDisplay(el, value)
    }
  },
  beforeUnmount(el, { value }) {
    setDisplay(el, value)
  }
}

2)v-if源码:返回一个node节点,render函数通过表达式的值来决定是否生成DOM

export const transformIf = createStructuralDirectiveTransform(
  /^(if|else|else-if)$/,
  (node, dir, context) => {
    return processIf(node, dir, context, (ifNode, branch, isRoot) => {
      // #1587: We need to dynamically increment the key based on the current
      // node's sibling nodes, since chained v-if/else branches are
      // rendered at the same depth
      const siblings = context.parent!.children
      let i = siblings.indexOf(ifNode)
      let key = 0
      while (i-- >= 0) {
        const sibling = siblings[i]
        if (sibling && sibling.type === NodeTypes.IF) {
          key += sibling.branches.length
        }
      }

      // Exit callback. Complete the codegenNode when all children have been
      // transformed.
      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
          )
        }
      }
    })
  }
)

0x03: 使用场景 v-if:运行条件很少改变 v-show:运行条件频繁改变


*二、 为什么Vue中的v-if和v-for不建议一起用?*

0x00: 意义
v-if: 条件性渲染
v-for: 基于一个数组来渲染一个列表(建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化)

0x01: 优先级
v2: v-if < v-for v3: v-if > v-for

0x02: 注意事项 v-if/v-for 不要放在同一个元素伤 1)v-if/v-for 在v2和v3上的优先级是相反的,在语义上难以区分 2)尽量是v-if的元素包括v-for, 这样先拿判断在确定要不要渲染循环,如果v-for在v-if外面渲染列表,每个循环都要判断 3)如果v-if出现在v-for内部,可通过计算属性来过滤那些不需要的选项 计算属性具有缓存的特性

computed: {
    items: function() {
      return this.list.filter(function (item) {
        return item.isShow
      })
    }
}

概括:
1)如果v-if和v-for同时存在,应该使用v-if包括v-for
2)如果v-for内部确实需要包括v-if,里面的判断使用计算属性提高性。



个人微信,欢迎交流 公众号:技术小难
简书
博客园 链接需要替换
CSDN
知乎
掘金
segmentfault

本文由 mdnice 多平台发布

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值