I have two classes declared.Goods
and User
class Goods {
#price: number
#quantity: number
constructor(price: number, quantity: number) {
this.#price = price;
this.#quantity = quantity;
}
get totalPrice() {
return this.#price * this.#quantity;
}
totalPriceFunc() {
return this.#price * this.#quantity;
}
}
class User {
private id: number
private name: string;
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
get info() {
return `id: ${this.id}, name: ${this.name}`;
}
infoFunc() {
return `id: ${this.id}, name: ${this.name}`;
}
}
init Goods
and User
and use vue3 ref
;
const g = new Goods(10, 100);
console.log('>>>>>>>g ref before: ', g.totalPrice, g.totalPriceGetFunc());
// >>>>>>>g ref before: 1000 1000
const gRef = ref<Goods>(g);
console.log('>>>>>>>g ref after: ', g.totalPrice, g.totalPriceGetFunc());
// >>>>>>>g ref after: 1000 1000
try {
console.log('gRef totalPrice: ', gRef.value.totalPrice);
console.log('gRef totalPriceGetFunc: ', gRef.value.totalPriceGetFunc());
} catch (e) {
console.error(e);
// TypeError: Cannot read private member #price from an object whose class did not declare it
// at get totalPrice (HelloWorld.vue:19:15)
// at Reflect.get (<anonymous>)
// at MutableReactiveHandler.get (reactivity.esm-bundler.js:928:25)
// at setup (HelloWorld.vue:50:46)
// at callWithErrorHandling (runtime-core.esm-bundler.js:199:19)
// at setupStatefulComponent (runtime-core.esm-bundler.js:7847:25)
// at setupComponent (runtime-core.esm-bundler.js:7808:36)
// at mountComponent (runtime-core.esm-bundler.js:5161:7)
// at processComponent (runtime-core.esm-bundler.js:5127:9)
// at patch (runtime-core.esm-bundler.js:4645:11)
}
-------------------------------------------------------------------
const u = ref<User>(new User(1, 'Daniel'));
console.log('u info: ', u.value.info);
// u info: id: 1, name: Daniel
console.log('u infoFunc: ', u.value.infoFunc());
// u infoFunc: id: 1, name: Daniel
Why is it that the #price
property of Goods
cannot be used when using ref
to declare responsive state, but private id private name
can be used normally?
Primitive values in Vue, such as #price
are not made "reactive" as the ref only tracks public properties. This is just the nature of Vue's framework.
It works when you use "private
", as it is coming from TypeScript, not Vue. It is a so-called compile time annotation and therefore will not be enforced at runtime. See more here.