在 vue 3 中安装应用程序后防止 运行 watchEffect 函数

Prevent running watchEffect function after app mounts in vue 3

我使用 onMounted + watchEffect 进行一些昂贵的渲染

现在每次应用程序安装 watchEffect 函数时 运行 也会

我如何才能 运行 仅在应用程序挂载时才执行函数

并自动阻止 watchEffect 运行 --> 仅 运行 它 道具值改变后

// parent

<template>
  <child :data="data" />

  <button type="button" @click="changeData">click to change</button>
</template>

<script>
import Child from "./components/child.vue";

export default {
  name: "App",
  components: {
    Child,
  },

  data() {
    return {
      data: [1],
    };
  },

  methods: {
    changeData() {
      this.data = [1, 2];
    },
  },
};
</script>

// Child



<template>
  <h1>I have this prop</h1>
</template>

<script>
import { onMounted, ref, watchEffect } from "@vue/runtime-core";

export default {
  name: "Child",
  props: ["data"],

  setup(props) {
    onMounted(() => {

// do this 

      watchEffect(() => {
        // if props.data data changes do this
      });
    });

    return {};
  },
};
</script>


不确定我是否理解你的问题,它应该运行,当应用程序挂载时,但也不是当它挂载时? 反正在setup方法里直接用watchEffect就可以了,何必嵌套在onMounted里呢。如果您只想听道具的变化,请改用 watchwatchEffect 运行在安装时使用一次,然后在更改任何使用的道具或参考时使用一次。

<template>
  <h1>I have this prop</h1>
</template>

<script>
import { onMounted, watch, watchEffect } from "@vue/runtime-core";

export default {
  name: "Child",
  props: ["data"],

  setup(props) {
    onMounted(() => {
      // do stuff once 
    });
    watchEffect(() => {
      // if mounted or if props.data data changes do this
    });
    watch(
      () => props.data,
      (data, prevData) => {
        // if props.data data changes do this
      }
    );

    return {};
  },
};
</script>

添加到 Thomas 答案的另一个建议是使用 watchEffectflush 选项作为 post

这将确保您的所有引用也得到解析

https://v3.vuejs.org/guide/reactivity-computed-watchers.html#effect-flush-timing

<template>
  <h1>I have this prop</h1>
</template>

<script>
import { watchEffect, watchPostEffect } from "@vue/runtime-core";

export default {
  name: "Child",
  props: ["data"],

  setup(props) {
    watchEffect(() => {
      // if mounted or if props.data data changes do this
    }, { flush: 'post' });

    // Vue 3.2+
    watchPostEffect(() => {
      // if mounted or if props.data data changes do this
    });

    return {};
  },
};
</script>