Search code examples
javascriptvue.jsvue-componentvuejs3vue-composition-api

Vue 3: computed property doesn't track its dependency in composition API


Consider this illustrative example:

const App = {
 setup() {
  const name = Vue.ref("");
  let firstTime = true;
  const message = Vue.computed(() => {
    if (firstTime) {
      firstTime = false;
      return "Welcome stranger";
    }
    return `Hello ${name.value}`;
  });
  
  return {
    name,
    message
  }
 }
};

Vue.createApp(App).mount("#root");
<script src="https://unpkg.com/vue@next"></script>
<div id="root">
  name: <input v-model="name"/> <br/>
  message: {{ message }}
</div>

As you can see, message stores a computed value that should track updates to name but it isn't.
Why is it like that and how to fix it?


Solution

  • Computed should always use an immutable reactive ref object you want to be computed.

    so if you declare the reactive objects you are using at the beginning it will work.

    const App = {
     setup() {
      const name = Vue.ref("");
      let firstTime = true;
      const message = Vue.computed(() => {
        name.value;
        if (firstTime) {
          firstTime = false;
          return "Welcome stranger";
        }
        return `Hello ${name.value}`;
      });
      
      return {
        name,
        message
      }
     }
    };
    
    Vue.createApp(App).mount("#root");
    <script src="https://unpkg.com/vue@next"></script>
    <div id="root">
      name: <input v-model="name"/> <br/>
      message: {{ message }}
    </div>