You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue2中调用this.$emit()后props为何无法即时更新?

Vue2中$emit后prop无法立即更新的原因解析

在Vue2里,调用this.$emit()触发父组件更新prop后,子组件无法立即获取到更新后的prop值,必须借助this.$nextTick()才能拿到最新结果,核心原因是Vue的异步更新队列机制。

原理说明

Vue为了避免频繁更新DOM带来的性能损耗,会将所有数据变更操作缓冲到一个异步队列中。当你在同步代码中修改数据(比如父组件通过$emit回调更新string),Vue不会立即更新DOM和子组件的prop,而是将这次变更加入队列。只有当当前事件循环中的所有同步代码执行完毕后,Vue才会统一处理队列中的变更,完成DOM更新和组件prop的同步。

结合代码流程拆解

  1. 子组件点击触发updateString方法,调用this.$emit("update-string", "a new string"),触发父组件的updateString回调,父组件将this.string设为新值。
  2. 父组件的string变更被加入Vue的异步更新队列,此时子组件的this.string仍保持旧值(空字符串),所以第一个console.log输出""。
  3. 当前同步代码执行完成后,Vue开始处理异步队列,将父组件的新值同步到子组件的string prop。
  4. this.$nextTick()的回调会在DOM更新完成(即prop同步完成)后执行,因此第二个console.log能输出最新的"a new string"。

官方文档参考

Vue2官方文档的「异步更新队列」章节明确说明了这一机制:Vue会缓冲同一事件循环中发生的所有数据变更,在下一个事件循环tick中,Vue会清除队列并执行必要的DOM更新。你可以通过Vue.nextTick()在DOM更新完成后执行回调,获取更新后的状态。

代码示例

Parent.vue

<template>
  <div id="parent">
    <UpdateProps :string="string" @update-string="updateString" />
  </div>
</template>

<script>
import UpdateProps from "./UpdateProps";

export default {
  name: "Parent",
  components: {
    UpdateProps,
  },
  data() {
    return {
      string: "",
    };
  },
  methods: {
    updateString(newString) {
      this.string = newString;
    },
  },
};
</script>

Child.vue

<template>
  <div @click="updateString">update string</div>
</template>

<script>
export default {
  name: "Child",
  props: {
    string: String,
  },
  emits: ["update-string"],
  methods: {
    updateString() {
      this.$emit("update-string", "a new string");
      console.log("updateString currently: ", this.string); // 输出 ""

      this.$nextTick(() => {
        console.log("updateString in $nextTick: ", this.string); // 输出 "a new string"
      });
    },
  },
};
</script>

内容的提问来源于stack exchange,提问作者bcjohn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:55:22