请你说一下Vue中v-if和v-for的优先级谁更高

  • v-if 与 v-for简介
    • v-if
    • v-for
    • v-if & v-for使用
  • v-if 与 v-for优先级比较
    • vue2 中,v-for的优先级高于v-if
      • 例子进行分析
    • vue3 v-if 具有比 v-for 更高的优先级
      • 例子进行分析
  • 总结
    • 在vue2中,v-for的优先级高于v-if
    • 在vue3中,v-if的优先级高于v-for

咋一听到这个题,如果自己没有试验过感觉还真容易说错,就像是会进入一个“思维误区”

就会理所当然的想如果这两个指令同时出现一个标签那是不是应该先if判断是否存在才会去渲染for的循环结构?

但实际是这样吗?

v-if 与 v-for简介

v-if

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染。

v-if是Vue.js中的一个指令,用于条件渲染,根据绑定的表达式的值的真假情况来决定是否显示或隐藏元素。

当v-if的表达式值为true时,元素会被渲染出来;当v-if的表达式值为false时,元素不会被渲染出来。

例如,下面代码中,如果isShow为true,则div元素将会被渲染,否则不会被渲染:

<template>
  <div v-if="isShow">
    show content
  </div>
</template>

需要注意的是,v-if指令会根据表达式的值动态地添加或删除元素,因此如果有频繁的切换操作,会影响性能。

此时可以考虑使用v-show指令,它只是简单地控制元素的显示或隐藏,并没有频繁的添加或删除元素。

v-for

v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组或者对象,而 item 则是被迭代的数组元素的别名。

v-for使用 的时候,建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化。

v-for是Vue.js中的一个指令,用于循环渲染数组或对象的数据。

v-for的用法有两种情况:

  1. 遍历数组:
    可以通过v-for指令循环渲染一个数组,将数组中的每个元素渲染成对应的元素或组件。语法形式为:v-for="item in array"

例如,下面代码中使用v-for指令循环渲染一个数组list中的每个元素:

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.id">
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: [
        { id: 1, name: 'Apple' },
        { id: 2, name: 'Banana' },
        { id: 3, name: 'Orange' }
      ]
    };
  }
}
</script>
  1. 遍历对象:
    可以通过v-for指令循环渲染一个对象的属性,将对象的属性和值渲染成对应的元素或组件。语法形式为:v-for="value, key in object"

例如,下面代码中使用v-for指令循环渲染一个对象info的每个属性:

<template>
  <div>
    <ul>
      <li v-for="(value, key) in info" :key="key">
        {{ key }}: {{ value }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      info: {
        name: 'John',
        age: 25,
        gender: 'Male'
      }
    };
  }
}
</script>

需要注意的是,在使用v-for时,需要为每个循环的元素或组件添加唯一的key属性,以便Vue.js能够跟踪每个节点的身份,并且在更新时进行高效的DOM操作。

更多详细内容,请微信搜索“前端爱好者戳我 查看

v-if & v-for使用

<ul> 
    <li v-for='user in users' :key='user.id'>{{user.name}}</li>
</ul> 
<footer v-if='user'>{{user}}</footer>

v-if 与 v-for优先级比较

  • 在vue2中,v-for的优先级高于v-if
  • 在vue3中,v-if的优先级高于v-for(Vue 3.0 已经调整了v-if和v-for 的优先级,故不存在渲染性能问题。)

vue2 中,v-for的优先级高于v-if

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。

官方文档:https://v2.cn.vuejs.org/v2/guide/conditional.html#v-if-%E4%B8%8E-v-for-%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8

在 Vue 2 中,不推荐在同一个元素上同时使用 v-if 和 v-for,主要是由于可能引发的性能问题和逻辑混淆。当 v-if 和 v-for 结合使用时,会导致以下问题:

  1. 性能问题: 当 v-if 和 v-for 同时存在于同一个元素上时,Vue 会在每次循环迭代时都重新渲染和销毁元素。这可能会导致不必要的 DOM 更新和性能下降,特别是在较长的列表上。这是因为每次循环迭代都会重新计算条件,并进行 DOM 操作。

  2. 逻辑混淆: 同时使用 v-if 和 v-for 会增加代码的复杂性和理解难度。将条件和循环逻辑分离可以使代码更加清晰,并让开发人员更容易理解和维护。

例子进行分析
<template>
  <div class="test-container">
     <div v-for="(item,index) in list" v-if="item === 9" :key="item" ></div>
  </div>
</template>
<script>
    export default {
      data(){
        return {
          numberArr:[1,2,3,4,5,6,7,8,9,10]
        }
      }
    };
</script>
<style scoped>
</style>

但是本段代码实际的逻辑为

this.numberArr.map(function (item,index) {
  if (item===9) {
    return item
  }
})

相反,最佳实践是:

将条件渲染 (v-if) 和列表渲染 (v-for) 分开处理。
可以使用计算属性或方法来处理数据,然后在模板中分别使用 v-if 和 v-for。

以下是一个示例代码:

<template>
  <div>
    <div v-if="showDiv" v-for="item in filteredItems" :key="item.id">
      {{ item.name }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showDiv: true,
      items: [
        { id: 1, name: 'Item 1', isActive: true },
        { id: 2, name: 'Item 2', isActive: false },
        { id: 3, name: 'Item 3', isActive: true }
      ]
    }
  },
  computed: {
    filteredItems() {
      return this.items.filter(item => item.isActive);
    }
  }
}
</script> 

在上述示例中,我们使用了计算属性 filteredItems 来过滤具有 isActive 属性的项目。

然后,我们在模板中使用 v-for 来渲染过滤后的结果,并使用 v-if 来条件性地渲染每个元素。这样可以保持逻辑的清晰和性能的优化。

vue3 v-if 具有比 v-for 更高的优先级

当 v-if 与 v-for 一起使用时,v-if 具有比 v-for 更高的优先级。

官方文档:https://cn.vuejs.org/guide/essentials/list.html#v-for-with-v-if

<!--
 这会抛出一个错误,因为属性 todo 此时
 没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>

推荐: 在外新包装一层 再在其上使用 v-for 可以解决这个问题 (这也更加明显易读):

<template v-for="todo in todos">
  <li v-if="!todo.isComplete">
    {{ todo.name }}
  </li>
</template>
例子进行分析
<template>
  <div class="test-container">
     <div v-for="(item,index) in numberArr" v-if="item === 9" :key="item"></div>
  </div>
</template>
<script>
export default {
  data(){
    return {
      numberArr: [1,2,3,4,5,6,7,8,9,10]   //需要遍历的数据
    }
  }
};
</script>
<style scoped>
</style> 

由于 v-if 优先级高,导致页面并没有进行渲染,控制台报错。

以下为控制台报错信息

[Vue warn]: Property "index" was accessed during render but is not defined on instance.

但是下面这种用法控制台并不会报错但是会警告

<template>
  <div class="test-container">
     <ul>
        <li v-for="(item, index) in objList" :key="index" v-if="item.isShow">
          {{ item.name }}
        </li>
      </ul>
  </div>
</template>
<script>
    export default {
      data(){
        return {
          objList:[
           { name: 'obj2', isShow: false },
           { name: 'obj2', isShow: true },
          ]
        }
      }
    };
</script>
<style scoped>
</style> 

但是这种写法也会有一个问题,无论是否符合v-if的条件都进行了报错

官方推荐的写法是这样的, 把 v-for 移动到容器元素上,例如ul,ol 或者外面包裹一层 template

<template>
  <div class="test-container">
     <ul>
         <template v-for="(item, index) in objList" :key="index">
          <li v-if="item.isShow">
            {{ item.name }}
          </li>
        </template>
      </ul>
  </div>
</template>
<script>
    export default {
      data(){
        return {
          objList:[
           { name: 'obj2', isShow: false },
           { name: 'obj2', isShow: true },
          ]
        }
      }
    };
</script>
<style scoped>
</style>

但如果想要有条件地跳过循环的执行,那么可以将v-if置于外层元素或者template上。

例如这样:

<template>
  <div class="test-container">
     <ul v-if="objList.length">
          <li v-for="(item, index) in objList" :key="index">
            {{ item.name }}
          </li>
      </ul>
  </div>
</template>
<script>
export default {
  data(){
    return {
      objList:[
           { name: 'obj2', isShow: false },
           { name: 'obj2', isShow: true },
      ]
    }
  }
};
</script>
<style scoped>
</style>

总结

在vue2中,v-for的优先级高于v-if

Vue 会在每次循环迭代时都重新渲染和销毁元素。

v-for比v-if优先级更高(可以说清结论的来源更好)。

如果同时出现在同一个标签上,则每次渲染都会先执行循环再进行条件判断,会造成较大的性能浪费。

解决办法有两种:

  • 先在外层套一个template来放置v-if,再嵌套v-for。
  • 借助computed计算属性代替v-if。

在vue3中,v-if的优先级高于v-for

注:Vue 3.0 已经调整了v-if和v-for 的优先级,故不存在渲染性能问题。

参考文档

  • https://www.nowcoder.com/discuss/513503986318696448
  • https://baijiahao.baidu.com/s?id=1766197354040903874&wfr=spider&for=pc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183196.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

61 权限提升-RedisPostgre令牌窃取进程注入

目录 演示案例:Redis数据库权限提升-计划任务PostgreSQL数据库权限提升Windows2008&7令牌窃取提升-本地Windows2003&10进程注入提升-本地pinjector进程注入工具针对-win2008以前操作系统pexec64 32进程注入工具针对-win2008及后操作系统- (佛系) 涉及资源: postgersql是…

2023亚太杯数学建模APMCM竞赛C题思路讲解:基于ARIMA与机理模型进行预测

本文针对6大问题,从多角度分析了我国新能源电动汽车发展形势与前景。文中针对不同问题,采用了层次分析法、时间序列模型、机理模型、回归模型等数学方法。并结合实例数据,对相关模型进行求解,以量化预测了新能源电动汽车在政策驱动、市场竞争、温室气体减排等多个方面的潜在贡献…

OpenCV快速入门:图像分析——图像分割和图像修复

文章目录 前言一、图像分割1.1 漫水填充法1.1.1 漫水填充法原理1.1.2 漫水填充法实现步骤1.1.3 代码实现 1.2 分水岭法1.2.1 分水岭法原理1.2.2 分水岭法实现步骤1.2.3 代码实现 1.3 GrabCut法1.3.1 GrabCut法原理1.3.2 GrabCut法实现步骤1.3.3 代码实现 1.4 Mean-Shift法1.4.1…

【分布式】小白看Ring算法 - 03

相关系列 【分布式】NCCL部署与测试 - 01 【分布式】入门级NCCL多机并行实践 - 02 【分布式】小白看Ring算法 - 03 【分布式】大模型分布式训练入门与实践 - 04 概述 NCCL&#xff08;NVIDIA Collective Communications Library&#xff09;是由NVIDIA开发的一种用于多GPU间…

Navicat 技术指引 | 适用于 GaussDB 的数据迁移工具

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对 GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

基于element-ui后台模板,日常唠嗑

后面会补充github地址 文章目录 目录 文章目录 案例说明 1.引入库 2.创建布局组件 3.创建布局组件 4.菜单效果展示 5.创建顶部组件 5.创建顶部面包屑组件 6.创建内容区域组件 7.效果总览 7.布丁&#xff08;实现一些小细节&#xff09; 前言一、pandas是什么&#xff1f;二、使…

Android Studio记录一个错误:Execution failed for task ‘:app:lintVitalRelease‘.

Android出现Execution failed for task :app:lintVitalRelease.> Lint found fatal errors while assembling a release target. Execution failed for task :app:lintVitalRelease解决方法 Execution failed for task ‘:app:lintVitalRelease’ build project 可以正常执…

计算机网络之网络层

一、概述 主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输 1.1网络引入的目的 从7层结构上看&#xff0c;网络层下是数据链路层 从4层结构上看&#xff0c;网络层下面是网络接口层 至少我们看到的网络层下面是以太网 以太网解决了什么问题&#xff1f; 答…

python中一个文件(A.py)怎么调用另一个文件(B.py)中定义的类AA详解和示例

本文主要讲解python文件中怎么调用另外一个py文件中定义的类&#xff0c;将通过代码和示例解读&#xff0c;帮助大家理解和使用。 目录 代码B.pyA.py 调用过程 代码 B.py 如在文件B.py,定义了类别Bottleneck&#xff0c;其包含卷积层、正则化和激活函数层&#xff0c;主要对…

微信小程序实现【点击 滑动 评分 评星(5星)】功能

wxml文件&#xff1a; <view class"wxpl_xing"><view class"manyidu">{{scoreContent}}</view><view><block wx:for{{scoreArray}} wx:for-item"item"><view classstarLen bindtapchangeScore data-sy"{{…

什么是LLC电路?

LLC电路是由2个电感和1个电容构成的谐振电路&#xff0c;故称之为LLC&#xff1b; LLC电路主要由三个元件组成&#xff1a;两个电感分别为变压器一次侧漏感(Lr)和励磁电感(Lm)&#xff0c;电容为变压器一次侧谐振电容(Cr)。这些元件构成了一个谐振回路&#xff0c;其中输入电感…

程序员进阶高管指南,看懂工资最少加5k

从象牙塔毕业跨入社会大染缸&#xff0c;很多人都跟我谈过他们的职业困惑&#xff0c;其中有一些刚刚毕业&#xff0c;有些人已经工作超过10年。基本上是围绕着怎样持续提升&#xff0c;怎样晋升为高级管理者。那么这篇文章&#xff0c;我就来谈一谈程序员到高管的跃升之路。 …

程序环境和预处理(详解版)

我们已经学到这里&#xff0c;这就是关于C语言的最后一个集中的知识点了&#xff0c;虽然它比较抽象&#xff0c;但是了解这部分知识&#xff0c;可以让我们对C代码有更深层次的理解&#xff0c;知道代码在每一个阶段发生什么样的变化。让我们开始学习吧! 目录 1.程序的翻译环…

5个免费在线工具推荐

NSDT 三维场景建模工具GLTF/GLB在线编辑器Three.js AI自动纹理化开发包YOLO 虚幻合成数据生成器3D模型在线转换 1、NSDT 三维场景建模 访问地址&#xff1a;NSDT 编辑器 2、GLTF/GLB在线编辑器 访问地址&#xff1a;GLTF 编辑器 3、Three.js AI自动纹理化开发包 图一为原始模…

C++类与对象(4)—日期类的实现

目录 一、类的创建和方法声明 二 、输出&运算符重载 三、检查合法性 1、获取对应年月的天数 2、初始化 四、实现加等和加操作 1、先写再写 2、先写再写 3、两种方式对比 五、实现自增和--自减 1、自增 2、自减 六、 实现减等和减操作 1、减等天数 2、加负数…

【数据结构/C++】线性表_双链表基本操作

#include <iostream> using namespace std; typedef int ElemType; // 3. 双链表 typedef struct DNode {ElemType data;struct DNode *prior, *next; } DNode, *DLinkList; // 初始化带头结点 bool InitDNodeList(DLinkList &L) {L (DNode *)malloc(sizeof(DNode))…

motionlayout的简单使用

MotionLayout 什么是motionLayout&#xff1f; MotionLayout 是 Android 中的一个强大工具&#xff0c;用于创建复杂的布局动画和过渡效果。它是 ConstraintLayout 的一个子类&#xff0c;继承了 ConstraintLayout 的布局功能&#xff0c;同时添加了动画和过渡的支持。Motion…

深度解析 Docker Registry:构建安全高效的私有镜像仓库

文章目录 什么是Docker Registry&#xff1f;Docker Hub vs. 私有RegistryDocker Hub&#xff1a;私有Registry&#xff1a; 如何构建私有Docker Registry&#xff1f;步骤一&#xff1a;安装Docker Registry步骤二&#xff1a;配置TLS&#xff08;可选&#xff09;步骤三&…

Adobe xd有免费版可以使用吗?

Adobexd现在收费了吗&#xff1f;Adobexd是收费的。Adobexd在中国提供个人版和团队版两项收费政策。个人版每月订阅60元&#xff0c;每年订阅688元&#xff1b;团队版每月订阅112元/用户&#xff0c;每年订阅1288元/用户。 虽然AdobeXD的免费计划已经下线&#xff0c;但Adobe仍…

穿山甲SDK 集成·android接入广告·app流量变现

接入穿山甲SDK的app 数独训练APP 广告接入示例: Android 个人开发者如何接入广告SDK&#xff0c;实现app流量变现 接入穿山甲SDK app示例&#xff1a; android 数独小游戏 经典数独休闲益智 随着移动互联网的快速发展&#xff0c;广告成为了许多应用开发者获取收益的主要方…