写点什么

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

作者:达摩
  • 2022 年 9 月 14 日
    陕西
  • 本文字数:1393 字

    阅读完需:约 5 分钟

前言:

原因:因为 v-for 优先级比 v-if 的优先级高,所以如果嵌套使用的话,每次 v-for 都会执行一次 v-if,而 v-if 是通过创建和销毁 dom 元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降,所以 vue 官方不推荐这样使用。


为什么说 v-for 优先级比 v-if 的优先级高?

v-if 与 v-for 都是 vue 模板系统中的指令

在 vue 模板编译的时候,会将指令系统转化成可执行的 render 函数


示例

1、编写一个 p 标签,同时使用 v-if 与 v-for

<div id="app">  <p v-if="show" v-for="item in arr">    {{ item.title }}  </p></div>
复制代码

2、创建 vue 实例,存放 show 与 arr 数据

const app = new Vue({ el: "#app", data() {  return {   arr: [    { title: "damo" },    { title: "damo2" }]  } }, computed: {  show() {   return this.arr && this.items.length > 0  } }})
复制代码

3、模板指令的代码都会生成在 render 函数中,通过 app.$options.render 就能得到渲染函数

ƒ anonymous() { with (this) { return   _c('div', { attrs: { "id": "app" } },   _l((arr), function (item)   { return (show) ? _c('p', [_v("\n" + _s(item.title) + "\n")]) : _e() }), 0) }}
复制代码

_l 是 vue 的列表渲染函数,函数内部都会进行一次 if 判断

得到结论:v-for 优先级是比 v-if 高


再看一个示例:可直观的感受到,v-if 和 v-for 一起使用所带来的性能影响

<template>  <div class="hello">     <div  v-for="(item,index) in list" v-if="index === 9" :key="item" ></div>  </div></template>
<script>export default { name: "IndexCom", data(){ return { list:[1,2,3,4,5,6,7,8,9,10] //需要遍历的数据 } }};</script>
复制代码

上面这组代码和下面这组是等价的

<template>  <div class="hello">    <div v-if="0 === 10"></div>   //第1次判断    <div v-if="1 === 10"></div>   //第2次判断    <div v-if="2 === 10"></div>   //第3次判断    <div v-if="3 === 10"></div>   //第4次判断    <div v-if="4 === 10"></div>   //第5次判断    <div v-if="5 === 10"></div>   //第6次判断    <div v-if="6 === 10"></div>   //第7次判断    <div v-if="7 === 10"></div>   //第8次判断    <div v-if="8 === 10"></div>   //第9次判断    <div v-if="9 === 10"></div>   //第10次判断  </div></template>
<script>export default { name: "IndexCom", data() { return { list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], }; },};</script>
复制代码


优化方案【避免一起使用的】

1、在 v-if 不依赖 v-for 的前提下,我们可以将 v-if 写在 v-for 的外层,这样就可以让 v-if 判断优先

2、当 v-if 的判断条件依赖于 v-for 的某个值时(item,index),我们可以提前过滤数组

<template>  <div class="hello">    <!-- 2. 然后这里去循环已经被过滤的属性 -->     <div  v-for="(item) in ListArr" :key="item" ></div>  </div></template>
<script>export default { name: "IndexCom", data(){ return { list:[1,2,3,4,5,6,7,8,9,10] } }, computed:{ //1. 在computed里先做好判断,这里过滤的成本远比v-if的成本低 ListArr(){ return this.list.filter((_,index) => index === 1) } }};</script>
复制代码


注:vue3 更新了 v-if 和 v-for 的优先级,使 v-if 的优先级高于 v-for


发布于: 刚刚阅读数: 5
用户头像

达摩

关注

还未添加个人签名 2019.12.04 加入

还未添加个人简介

评论

发布
暂无评论
为什么Vue中的v-if和v-for不建议一起用_Vue_达摩_InfoQ写作社区