typescriptvue.jsclasspropertiesreactive

How to make a class getter reactive in Vue.js 3 with Composition API?


I'm trying to make a class instance property reactive to display the error message if authentication fails.

userModel.ts

export class User {
  private error: string;

  set errorMessage(errorMessage: string) {
    this.error = errorMessage;
  }
  get errorMessage() {
    return this.error
  }

// other stuff...
}

LoginView.vue

import { User } from "./models/userModel";
import { ref } from 'vue';

const user = new User();
const errorMessage = ref(user.errorMessage); // <--- This is not working.
const errorMessage = ref(user.error); // <--- Neither this even if user.error property is public.

No warnings or exceptions, reactive value just remains empty. What I am missing?


Solution

  • Here, you are creating new reactive variables, with the initial value being the one in your class. Your class and your ref are unrelated.

    If you want your class to have reactive properties, you have to instanciate them this way:

    export class User {
      private error: Ref<string> = ref('');
    
      public errorMessage: WritableComputedRef<string> = computed({
        get() {
          return this.error.value
        },
        set(errorMessage: string) {
          this.error.value = errorMessage;
        },
      })
    }
    

    Side note: I'd recommend to use the "composables" approach instead of using classes, because class instances are not compatible with SSR.

    export function useUser () {
      const user: User = reactive({})
      // other stuff...
    
      const error: Ref<string> = ref('');
    
      const errorMessage: WritableComputedRef<string> = computed({
        get() {
          return this.error.value
        },
        set(errorMessage: string) {
          this.error.value = errorMessage;
        },
      })
    
      return { user, errorMessage }
    }