Element 自定义标签页(el-tab) 下的 el-badge 视图不渲染

4,413 阅读1分钟

需求:用户在进入这个页面时,能看到标签页(el-tab)上的代办数字标记(el-badge)

问题:el-badge绑定的变量是有数据的,但是界面上就是不渲染。

代码:

  <el-tabs>
    <el-tab-pane>
      <span slot="label">
        <i class="el-icon-message">人员信息</i>
        <el-badge :value="todo" v-if="todo>0" size="mini" class="item"></el-badge>
      </span>
    </el-tab-pane>
    <el-tab-pane label="用户管理" name="user"></el-tab-pane>
  </el-tabs>
</template>
<script>
  export default {
    data() {
      return {
        todo: 0,
      }
    },
    mounted() {
      //代办数据
      getTodo() {
        this.$http({
          method: "post",
          url: `...`,
          params: {...}
        }).then(res => {
          console.log("代办数据请求成功", res.data.data.todoNum);
          this.todo = res.data.data.todoNum || 0;
        })
      }, 
    },
    created() {
    }
  }
</script>

在 getTodo 里成功打印了:代办数据请求成功 1

然而视图如下:

当点击tab标签时,标记出来了:

查阅了相关资料,发现 vue 官网上有下面一段话:

示例:
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

强制更新
如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事。
你可能还没有留意到数组或对象的变更检测注意事项,或者你可能依赖了一个未被 Vue 的响应式系统追踪的状态。
然而,如果你已经做到了上述的事项仍然发现在极少数的情况下需要手动强制更新,那么你可以通过 $forceUpdate 来做这件事。
解决:

在getTodo请求到数据之后增加一句:

this.$children[0].$children[0].$forceUpdate();

然后打开页面时,标签页上的标记就出现了:

原因分析:组件层级嵌套深了有可能会出现子组件不重新渲染的情况(我对这个解释很不满意,后续补上...)