v-if和v-for需要共用的解决办法

148 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

我们都知道v-ifv-for不能共用,因为v-for优先级是比v-if高, 两者一起使用会不停地循环判断,而v-if用于条件性地渲染所在元素块内容,所以造成严重的性能浪费。

但是在实现项目需求时,我们有时候又需要同时使用两者,最常用的解决办法是把v-if写在v-for的外层,这样就可以让v-if的优先级大于v-for,就不用去判断很多次:

// v-if写在v-for的外层 这样就可以让v-if的优先级大于v-for,就不用去判断很多次
<template>
  <div class="container">
    <div  v-if="isShown"><a-select
      v-model="searchCriteria.id"
    >
      <a-option
        v-for="item of allData"
        :key="item.id"
        :value="item.cuid"
        :label="`${item.id}-${item.name}`"
      />
    </a-select>
    </div>
  </div>
</template>

const isShown =  false;
const allData = [ ... ];

但其实呢,这么写有个大问题,本人代码实测发现,如果刚开始v-if的条件不满足,下拉框隐藏,后来经过某种操作,v-if的条件满足之后,下拉列表显示,但是循环的选项太多的话(我本人项目中选项100多条将近200条,或许你觉得我应该用远程搜索下拉选项,但是产品经理不喜欢。。。),下拉选择的出现就会有点卡(是选项的出现卡,不是下拉列表本身)

或许有的需求场景下也可以用v-show,但是v-show的话会留下该下拉框绑定的值,所以还需要在隐藏的时候手动清空绑定的值...

后来找到另一个解决办法,但觉得也不是最好的办法:就是设置一个额外的变量,在隐藏之前清空select的下拉选项,需要展示的时候,先显示下拉框,然后再给选项赋值,说起来有点绕,看代码吧:

<template>
  <div class="container">
    <div  v-if="isShown"><a-select
      v-model="searchCriteria.id"
    >
      <a-option
        v-for="item of allData"
        :key="item.id"
        :value="item.cuid"
        :label="`${item.id}-${item.name}`"
      />
    </a-select>
    </div>
  </div>
</template>

let isShown =  false;
let allData = [ ];
const thirdArray = [  ...这里放的数据 ];

// 在某个控制isShown的事件中
const handleIsShow = () = {
    allData = [ ];  // 先清空
    isShown = !isShown;  // 再判断
    allData = isShown ? thirdArray : [];
};

希望本文对你有所帮助!