Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

The flush property of watch does not work when it is post #12897

Open
someBrown opened this issue Dec 9, 2022 · 0 comments
Open

The flush property of watch does not work when it is post #12897

someBrown opened this issue Dec 9, 2022 · 0 comments

Comments

@someBrown
Copy link

someBrown commented Dec 9, 2022

Version

2.7.14

Reproduction link

codesandbox.io

Steps to reproduce

https://codesandbox.io/s/quizzical-grass-85c9zw?file=/src/components/HelloWorld.vue

What is expected?

if watch has set flush to 'post', it's callback should be called after
dom rerender,so that the callback function can get the latest dom

What is actually happening?

The parent component passes a test property to the child component,and the parent component will change this test property when the button is clicked

<template>
  <div id="app">
    <button @click="click">click me!</button>
    <HelloWorld msg="Hello Vue in CodeSandbox!" :test="test" />
  </div>
</template>

<script >
import HelloWorld from "./components/HelloWorld";
import { ref } from "vue";
export default {
  components: { HelloWorld },
  setup() {
    const test = ref(false);
    const click = () => {
      console.log("click");
      test.value = true;
    };

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

The child component will get the latest dom info in watch after the test property has changed,but it cannot get the latest dom. The {flush: "post"} config not work

<template>
  <div class="hello" :class="{ test }">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
import { getCurrentInstance, watch, nextTick } from "vue";
export default {
  name: "HelloWorld",
  props: {
    msg: String,
    test: Boolean,
  },
  setup() {
    const vm = getCurrentInstance().proxy;
    console.log(vm.$props.test);
    watch(
      () => vm.$props.test,
      () => {
        // should print element but print null
        console.log(document.querySelector(".test"));
        nextTick(() => {
          console.log(document.querySelector(".test"));
        });
      },
      {
        flush: "post",
      }
    );
  },
};
</script>

Because when already flushing,no sorting of new incoming watchers based on the post attribute

// if already flushing, splice the watcher based on its id
    // if already past its id, it will be run next immediately.
    let i = queue.length - 1
    while (i > index && queue[i].id > watcher.id) {
      i--
    }
    queue.splice(i + 1, 0, watcher)
someBrown pushed a commit to someBrown/vue that referenced this issue Dec 9, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant