#独家
使用template标签包裹的话,必须严格的v-if + v-else-if + v-else判断就不会出问题

2025-05-01 0 2,169

vue2中使用template包裹了两个el-button,并且template添加了判断条件,但是当showSteps值变化为3时,其中设置了disabled的‘生成’按钮禁用属性失效,仍然可以点击,elementui版本:2.15.14;webpack版本:3.12.0,vue版本:2.7.16 代码如下

<template>
  <div>
    <el-input-number v-model="showSteps"></el-input-number>
    <el-button size="small" :disabled="!canSave">关闭</el-button>

    <template v-if="![3, 4, 6].includes(showSteps)">
      <el-button v-if="showEdit" size="small">edit</el-button>
    </template>
    <template v-if="showSteps === 3">
      <el-button type="success" size="small">赋值</el-button>
      <el-button type="primary" size="small" :disabled="!canSave">生成</el-button>
    </template>
    <template v-else>
      <el-button v-if="false" type="primary" size="small" :disabled="!canSave">next</el-button>
    </template>
  </div>
</template>

<script>
export default {
  data() {
    return {
      canSave: false,
      showSteps: 1,
      dataStep: 4,
    }
  },
  computed: {
    showEdit() {
      return this.showSteps <= this.dataStep && this.editStep !== this.showSteps
    }
  },
}
</script>

目前已知将template标签更换为span、或者为’生成’按钮添加key可以解决这个问题,求助各位是什么样原因导致了这个问题

使用template标签包裹的话,必须严格的v-if + v-else-if + v-else判断就不会出问题

为什么用 v-if 判断会失效?

每个模块会单独挂载/销毁每一块 DOM,造成:

  • 条件切换时原有的 DOM 可能被销毁又重新创建;
  • 某些状态(比如绑定的 :disabled)会丢失或初始化异常;
  • 尤其在 template 里嵌套多个块的时候,Vue 的虚拟 DOM diff 策略可能出现不稳定行为。

为什么用 v-else-if 就没问题?

因为 v-if + v-else-if + v-else 是一个连续块,Vue 会把它们当作一个整体处理,不会销毁和重建 DOM,而是根据条件“启用或禁用当前分支”。 这样状态就不会中间被“抛失”,所有绑定(比如 :disabled)也会正确应用。这样就能保证:

  • 所有分支是“互斥”的;
  • Vue 渲染时只保留一个逻辑分支;
  • DOM 不被反复销毁与重建,响应式绑定更稳定。

那为什么将template换成span也是可以的?

原因是:<template> 本身不渲染成实际 DOM 元素

  • 每个 <template> 是“虚拟容器”,Vue 会动态添加/移除内部元素;
  • 如果条件快速变化(比如 condA → condB → condA),Vue 可能需要频繁地销毁/重建里面的 <button>;
  • 这会造成状态丢失,或者某些属性(如 :disabled)暂时失效。

span又是好的,原因:

  • <span> 是真实 DOM 元素,Vue 会保留这段元素,即使它当前不显示;
  • 因为真实 DOM 存在,Vue 的 Virtual DOM diff 算法会尽量复用已有 DOM,不会反复销毁重建;
  • 所以按钮状态更稳定,像 :disabled 不容易失效。

当然加key的原因这个就不用说了,显式根据key重新渲染保证渲染一致性。

Edit

看起来是 diff 算法的问题,认为是同一个node节点了。
可以这样修改一下👇

<template v-if="![3, 4, 6].includes(showSteps)">
  <el-button v-if="showEdit" size="small">edit</el-button>
</template>
- <template v-if="showSteps === 3">
+ <template v-else-if="showSteps === 3">
  <el-button type="success" size="small">赋值</el-button>
  <el-button type="primary" size="small" :disabled="!canSave">生成</el-button>
</template>
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

1. JK下载官网所有资源来源于开发团队,加入会员即可下载使用!如有问题请联系右下角在线客服!
2. JK下载官方保障所有软件都通过人工亲测,为每位会员用户提供安全可靠的应用软件、游戏资源下载及程序开发服务。
3. JK开发团队针对会员诉求,历经多年拥有现今开发成果, 每款应用程序上线前都经过人工测试无误后提供安装使用,只为会员提供安全原创的应用。
4. PC/移动端应用下载后如遇安装使用问题请联系右下角在线客服或提交工单,一对一指导解决疑难。

JK软件下载官网 技术分享 使用template标签包裹的话,必须严格的v-if + v-else-if + v-else判断就不会出问题 https://www.jkxiazai.com/4410.html

JK软件应用商店是经过官方安全认证,保障正版软件平台

相关资源

官方客服团队

为您解决烦忧 - 24小时在线 专业服务