Skip to content

v-for和v-if在同一标签使用时

缘由

  • 在进行项目开发的时候因为在一个标签上同时使用了v-for和v-if两个指令导致的报错。

报错代码如下

html
<el-input
      type="textarea"
     :autosize="{ minRows: 2, maxRows: 8}"
     v-for="Oitem in Object.keys(cItem)"
     :key="Oitem"
     v-if="Oitem !== 'title'"
     v-model="cItem[Oitem]">
</el-input>

提示错误

The 'undefined' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'

错误原因:v-for的优先级高于v-if,因此v-if会重复运行在每个v-for中,性能损耗严重

当v-for和v-if同时应用于同一标签时,会出现一些问题。在Vue中,v-for的优先级比v-if更高,这意味着v-for会在v-if之前被解析和执行。

具体来说,如果v-for和v-if都应用于同一标签,那么在每次迭代中,都会先执行v-for,生成相应的DOM元素,然后再根据v-if的条件进行筛选。

这可能导致不必要的渲染:由于v-for先执行,即使v-if的条件为false,仍然会生成对应的DOM元素。然后这些元素在后续的条件判断过程中被决定是否显示或隐藏。这会导致不必要的DOM渲染,降低性能。

解决

  • 将v-if放在外层元素或使用template包裹:将v-if应用于包裹元素或template标签,而不是与v-for共用同一标签,以确保条件判断在循环之前执行。
html
<div v-if="condition">
  <div v-for="item in items" :key="item.id">
    <!-- 循环内容 -->
  </div>
</div>
  • 使用计算属性或过滤器:根据特定的条件,通过计算属性或过滤器来生成一个新的数组,并将v-for应用于新的数组。这样可以确保只渲染满足条件的元素。
html
<div v-for="item in filteredItems" :key="item.id">
  <!-- 循环内容 -->
</div>

computed: {
  filteredItems() {
    return this.items.filter(item => item.condition);
  }
}

综上所述,为了避免潜在的问题和提高性能,最好将v-for和v-if分开使用,或者考虑使用计算属性或过滤器来处理筛选逻辑。