slot插槽v-if条件渲染没生效或者混乱

3,154 阅读1分钟

vue 在使用匿名插槽时,通过v-if条件来动态显示某些节点,发现有的节点渲染没生效或者混乱

`

  <template v-if="selectedButton === '-1' || selectedButton === '1'">
    <el-button
      v-if="selectedButton === '1'"
      type="primary"
      v-permission="['exportResults']"
    >
      导出结果
    </el-button>
    <el-button v-permission="['timeDelay']" type="primary">
      时效延迟
    </el-button>
    <el-button
      v-if="selectedButton === '-1'"
      v-permission="['dataRecycle']"
      type="primary"
    >
      数据回收
    </el-button>
    <el-button v-permission="['scheduleTask']" type="primary">
      调配任务
    </el-button>
  </template>

`

如果所有按钮有权限且selectedButton的值为-1,效果 image.png

如果所有按钮有权限selectedButton的值为1,效果 image.png 真实场景:

selectedButton的值默认为-1,调配任务按钮有查看权限,导出结果、时效延迟、数据回收无查看权限(默认效果) image.png

  1. 切换改变为1(效果1) image.png
  2. 再次切换改变为-1(效果2)

因按钮有权限控制,不应该显示时效延迟、数据回收按钮,却显示出来了,而且顺序也不对,按理调配任务应该显示在最后 image.png 重复切换,总是效果1、效果2

问题:

效果2的结果不对,不应该显示示时效延迟、数据回收按钮

原因:

因为vue虚拟dom机制,会尽量复用已存在相同节点元素而不会重新渲染,导致使用v-if没有达到预期效果

方法:

使用div元素将slot插槽内容包裹起来,并在div元素上使用key,插槽内容才会重新渲染 `

  <div :key="selectedButton" v-if="selectedButton === '-1' || selectedButton === '1'">
    <el-button
      v-if="selectedButton === '1'"
      type="primary"
      v-permission="['exportResults']"
    >
      导出结果
    </el-button>
    <el-button v-permission="['timeDelay']" type="primary">
      时效延迟
    </el-button>
    <el-button
      v-if="selectedButton === '-1'"
      v-permission="['dataRecycle']"
      type="primary"
    >
      数据回收
    </el-button>
    <el-button v-permission="['scheduleTask']" type="primary">
      调配任务
    </el-button>
  </div>

`

vue的Diff算法判断新旧节点为同一类型节点时,就不会重新渲染节点,而是更新变化