Vue技巧大揭秘:v-show与v-if的区别及性能对比一目了然

简介: 欢迎来到前端入门之旅!

⭐  专栏简介


       欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。



       同时,我们也会关注最新的前端趋势和发展动态。随着Web技术的不断演进,前端开发也在不断推陈出新。我们会及时介绍最新的前端框架、工具和技术,使你能够站在前沿,与时俱进。通过掌握最新的前端技术,你将能够在竞争激烈的Web开发领域中有更大的竞争力。



📘  文章引言


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


我们都知道在 vue 中 v-show  与 v-if 的作用效果是相同的(不含v-else),都能控制元素在页面是否显示


在用法上也是相同的

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


当表达式为true的时候,都会占据页面的位置

当表达式都为false时,都不会占据页面位置


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


控制手段不同

编译过程不同

编译条件不同

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


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


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


v-show 由false变为true的时候不会触发组件的生命周期


v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法


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


三、v-show与v-if原理分析


具体解析流程这里不展开讲,大致流程如下


将模板template转为ast结构的JS对象

用ast得到的JS对象拼装render和staticRenderFns函数

render和staticRenderFns函数被调用后生成虚拟VNODE节点,该节点包含创建DOM节点所需信息

vm.patch函数通过虚拟DOM算法利用VNODE节点创建真实DOM节点


v-show原理


不管初始条件是什么,元素总是会被渲染


我们看一下在vue中是如何实现的


代码很好理解,有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原理


v-if在实现上比v-show要复杂的多,因为还有else else-if 等条件需要处理,这里我们也只摘抄源码中处理 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
          )
        }
      }
    })
  }
)


四、v-show与v-if的使用场景


v-if 与 v-show 都能控制dom元素在页面的显示


v-if 相比 v-show 开销更大的(直接操作dom节点增加与删除)


如果需要非常频繁地切换,则使用 v-show 较好


如果在运行时条件很少改变,则使用 v-if 较好



⭐  写在最后


请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.


✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式


✅ 认为我部分代码过于老旧,可以提供新的API或最新语法


✅ 对于文章中部分内容不理解


✅ 解答我文章中一些疑问


✅ 认为某些交互,功能需要优化,发现BUG


✅ 想要添加新功能,对于整体的设计,外观有更好的建议


最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关文章
|
2天前
|
JavaScript 前端开发 Java
【vue实战项目】通用管理系统:作业列表
【vue实战项目】通用管理系统:作业列表
15 0
|
2天前
|
JavaScript API
【vue实战项目】通用管理系统:信息列表,信息的编辑和删除
【vue实战项目】通用管理系统:信息列表,信息的编辑和删除
12 2
|
2天前
|
JavaScript API
【vue实战项目】通用管理系统:信息列表,信息录入
【vue实战项目】通用管理系统:信息列表,信息录入
8 3
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1001 0
|
8天前
|
JavaScript 前端开发 开发者
vue3+ts配置跨域报错问题解决:> newpro2@0.1.0 serve > vue-cli-service serve ERROR Invalid options in vue.
【6月更文挑战第3天】在 Vue CLI 项目中遇到 &quot;ERROR Invalid options in vue.config.js: ‘server’ is not allowed&quot; 错误是因为尝试在 `vue.config.js` 中使用不被支持的 `server` 选项。正确配置开发服务器(如代理)应使用 `devServer` 对象,例如设置代理到 `http://xxx.com/`: ```javascript module.exports = { devServer: {
22 1
|
2天前
|
JavaScript 前端开发 API
【vue实战项目】通用管理系统:学生列表
【vue实战项目】通用管理系统:学生列表
12 2
|
2天前
|
缓存 JavaScript
【vue实战项目】通用管理系统:首页
【vue实战项目】通用管理系统:首页
9 2
|
2天前
|
JavaScript 前端开发 数据安全/隐私保护
【vue实战项目】通用管理系统:登录页
【vue实战项目】通用管理系统:登录页
10 2
|
2天前
|
JavaScript 网络架构
Vue中三个点(...)的意思
**孤立元素**:通过扩展运算符(`...`)可以将数组元素打印出来,如 `console.log(...iArray)`。 - **添加元素**:可以使用扩展运算符结合数组合并来添加元素,例如 `[&#39;0&#39;, ...iArray, &#39;4&#39;]` 或者使用 `push` 方法。 - **删除元素**:通过解构赋值取出数组第一个元素,如 `const [first, ...last] = arr`。 - **数组合并**:可以使用扩展运算符将多个数组合并,如 `[...arr1, ...arr2]`。
5 0
|
2天前
|
JavaScript 前端开发
vue filters过滤器传多个参数
这段内容展示了如何在HTML和JavaScript中使用过滤器(filter)。在HTML中,通过`{{变量 | 过滤器名(参数)}}`的方式传递参数给过滤器。在JavaScript中,定义过滤器函数并接收参数,如`filterAa(aa, bb, cc)`,其中`aa`, `bb`, `cc`分别代表过滤器接收到的第1至第3个参数。示例逐步演示了传1个、2个到3个参数给过滤器的过程。
9 1