ITADN
vuejs/core/Issues

Object.defineProperty bypasses reactive array reactivity

#15182Openmmmmaharshi 创建于 24 天前
🔩 p2-edge-case
M
mmmmaharshicommented
## Description `Object.defineProperty` and `Reflect.defineProperty` on a reactive array set values without notifying observers. The `defineProperty` Proxy trap exists but does not call `trigger()` for array indices. ## Reproduction ```js import { reactive, effect } from "@vue/reactivity" const arr = reactive([1, 2, 3]) let v effect(() => { v = arr[0] }) console.log(v) // 1 arr[0] = 10 // ✅ v === 10 (notified) Object.defineProperty(arr, "0", { value: 999 }) console.log(v) // ❌ 10 (stale! arr[0] is actually 999) ``` Affects: existing index values, new index creation at `arr[arr.length]`, and `arr.length` modification via `defineProperty`. ## Impact Any code that uses `Object.defineProperty` on a reactive array — including test frameworks (Jest mockImplementation, Sinon stubs), serialization libraries, and polyfills — silently produces stale downstream computations. ## Analysis Vue 3s reactive Proxy does have a `defineProperty` trap (it handles `__v_skip` and `__v_raw` flags), but it does not call `trigger()` for numeric string keys that correspond to array indices. The `set` trap correctly triggers, but `defineProperty` provides a parallel mutation path. Found by the reactive array conformance suite (8 mutation traces across 4 reactive implementations).
2 条评论