Property added with Object.defineProperty() is not reactive
Vue version
3.2.45
Link to minimal reproduction
(Redacted, see https://github.com/vuejs/core/issues/7602#issuecomment-1779339124)
Steps to reproduce
Click "Set next (a)" on the first item. Observe that nothing happens. Click "Set next (b)" on the second item. Notice that not only its own number updates, but also the previous one.
What is expected?
I'd have expected Object.defineProperty()
to behave the same as regular [[Set]]
wrt reactivity.
What is actually happening?
Only regular assignment seems to create reactive properties.
System Info
No response
Any additional comments?
There is a separate proxy trap for Object.defineProperty
, possibly only set()
is currently used?
When running the example on SFC there's a warning stating you shouldn't be using v-for
scoped for v-model
, which is correct, in your example you v-model
to a primitive number
playground
So ignoring the example and circle back to the Object.defineProperty
, I'm not sure if it should be reactive, what is the actual use case of it?
Not saying I don't agree with supporting this, but just wondering why Object.defineProperty
is used instead of assigning directly through .[prop]
@vaakian @liuseen-l if you guys have insight on this, since you created the PRs :)
@pikax
When running the example on SFC there's a warning stating you shouldn't be using
v-for
scoped forv-model
, which is correct, in your example youv-model
to a primitive number playground
Wow, it appears I posted the wrong link. This looks like a demo for my students to explain that v-model
on primitives in v-for
doesn't work, rather than a testcase for this bug. 🤦🏽♀️🤦🏽♀️🤦🏽♀️ I mean, even the buttons I'm referencing in the issue aren't there 😅
Worse, I cannot seem to find the original testcase anywhere (I suspect CodePen had autosave on and I accidentally overwrote it 😭) and any attempt to recreate it has failed.
So ignoring the example and circle back to the
Object.defineProperty
, I'm not sure if it should be reactive, what is the actual use case of it?Not saying I don't agree with supporting this, but just wondering why
Object.defineProperty
is used instead of assigning directly through.[prop]
Are you asking why Object.defineProperty()
exists? 😅 Two main reasons:
- Creating accessors (not relevant here)
- Creating data properties that are not enumerable, not configurable, or both (very relevant)
There is no reason why non-enumerable/non-configurable properties should not be reactive, these are entirely orthogonal concepts.
Are you asking why
Object.defineProperty()
exists?
No, I'm asking a use case for it, where it must not be enumerable or not configurable but still being reactive.
You can still have a reactive by just returning on get the reactive
const obj2 = reactive({
a: 1
})
Object.defineProperty(obj2, 'b', {
enumerable: false,
get() {
return b.value
},
})
// or
Object.defineProperty(obj, 'b', {
enumerable: false,
writable: true
})