I'm trying to create a class with a ComputedRef<> field, and assign its object to a component property. But the computed property is not updated.
/// Student.ts
import { computed, type ComputedRef } from "vue";
export class Student {
age: number;
adult: ComputedRef<boolean>;
constructor(age: number) {
this.age = age;
const that = this;
this.adult = computed(() => that.age >= 18);
}
}
/// StudentComponent.vue
<script setup lang="ts">
import { Student } from './student';
import { ref } from 'vue';
const props = defineProps<{
data: Student
}>();
const dataRef = ref(props.data);
</script>
<template>
<div>age: {{ dataRef.age }}</div>
<div>adult: {{ dataRef.adult }}</div>
<button @click="++dataRef.age;">+1</button>
<button @click="--dataRef.age;">-1</button>
</template>
</script>
/// App.vue
<script setup lang="ts">
import StudentComponent from './StudentComponent.vue';
import { Student } from './student';
const student = new Student(18);
</script>
<template>
<StudentComponent :data="student"></StudentComponent>
</template>
The result is below:
"adult" value is not changed when "-1" button is clicked. How should I do it?
The computed value will only update when any referenced 'ref's are updated. Since the class property 'age' is just a number not a ref, the computed property will not know when a new value is set.
It should work if you update your class to use a ref for the 'age' property:
import { ref, type Ref, computed, type ComputedRef } from "vue";
export class Student {
age: Ref<number>;
adult: ComputedRef<boolean>;
constructor(age: number) {
this.age = ref(age);
this.adult = computed(() => this.age.value >= 18);
}
}
make sure you update the age property through using studentInstance.age.value = newValue
.
You can also 'hide' the fact that you're using a ref in the class using getter/setter with a private property
import {ref, type Ref, computed, type ComputedRef } from 'vue'
export class Student {
_age: Ref<number>
adult: ComputedRef<boolean>
get age() {
return this._age.value
}
set age(newVal: number) {
this._age.value = newVal
}
constructor(age: number) {
this._age = ref(age)
this.adult = computed(() => this._age.value >= 18)
}
}
which will let you update values normally studentInstance.age = newValue