typescript - Wie macht man einen Klassen-Getter in Vue.js 3 mit der Composition API reaktiv?
Ich versuche, eine Eigenschaft einer Klasseninstanz reaktiv zu machen, um die Fehlermeldung anzuzeigen, falls die Authentifizierung fehlschlägt.
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.
Keine Warnungen oder Ausnahmen, der reaktive Wert bleibt einfach leer. Was fehlt mir?
Antwort #1
Hier erstellen Sie neue reaktive Variablen, wobei der Anfangswert derjenige aus Ihrer Klasse ist. Ihre Klasse und Ihr ref sind nicht miteinander verbunden.
Wenn Sie möchten, dass Ihre Klasse reaktive Eigenschaften hat, müssen Sie sie auf diese Weise instanziieren:
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;
},
})
}
Nebenbei bemerkt: Ich würde empfehlen, den „Composables“-Ansatz anstelle von Klassen zu verwenden, da Klasseninstanzen mit SSR nicht kompatibel sind.
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 }
}
Antwort #2
Der Zugriff auf eine primitive Eigenschaft nach Wert wie ref(user.error) kann nicht reaktiv sein, egal ob es sich um einen Getter handelt oder nicht, in diesem Fall unterscheidet es sich nicht von ref(undefined).
Für eigene aufzählbare Eigenschaft könnte es sein:
let user = reactive(new User());
let { error } = toRefs(user);
Es wird keine Eigenschaftszugriffe behandeln, sie müssen explizit mit einer berechneten Eigenschaft zugegriffen werden:
let errorMessage = computed({
get: () => user.errorMessage,
set: value => { user.errorMessage = value }
});
Ob es sich um einen Getter oder eine normale Eigenschaft handelt, beeinflusst nicht, wie ein Computed funktioniert, da ein Accessor im Klassenprototyp definiert ist und auf reaktives this.error zugreift (dies kann ein Problem sein, wenn nicht-reaktives this im Konstruktor gebunden wird, wie hier und hier gezeigt).
