Subscribe on changes!

Cant get dom automatically when put the `ref` of directive in v-else branch

avatar
Jan 16th 2021

Version

3.0.5

Reproduction link

https://codesandbox.io/s/suspicious-wright-n3pi5?file=/src/App.vue

Steps to reproduce

<template>
  <a v-if="isShow" />
  <button v-else ref="el">el</button>
</template>

<script>
import { ref, watchEffect } from "vue";
export default {
  name: "App",
  setup() {
    const el = ref();
    const isShow = ref(true);

    setTimeout(() => {
      isShow.value = false;
    }, 3000);

    watchEffect(() => {
      console.log("change", el.value); // `undifined`
    });

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

What is expected?

should be get button

What is actually happening?

get undifined and just called once

avatar
Jan 16th 2021

watchEffect is flushed in 'pre' mode by default, which means its run before the DOM is updated. When working with template refs, which are updated after the DOM has been updated, you need to use flush: 'post'

    watchEffect(() => {
      console.log("change", el.value);
    }, { flush: 'post' });

Related: #2730, #2732