Skip to content

Commit

Permalink
fix: fix vue2 array reactive bug (#4042)
Browse files Browse the repository at this point in the history
* fix: fix vue2 array reactive bug

* test: add observable __proto__ test case
  • Loading branch information
yiyunwan authored Dec 7, 2023
1 parent 588e5e5 commit c94da3f
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
14 changes: 14 additions & 0 deletions packages/reactive/src/__tests__/observable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ test('observable contains', () => {
expect(contains(obj, obj.arr)).toBe(true)
expect(contains(obj, arr)).toBe(true)
})

test('observable __proto__', () => {
const observableArr = observable([] as any[])
// @ts-ignore
observableArr.__proto__ = Object.create(Array.prototype)
observableArr[0] = {}
expect(observableArr).toEqual([{}])

const observableObj = observable({} as any)
// @ts-ignore
observableObj.__proto__ = Object.create(Object.prototype)
observableObj.aa = {}
expect(observableObj).toEqual({ aa: {} })
})
18 changes: 11 additions & 7 deletions packages/reactive/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import { isObservable, isSupportObservable } from './externals'
import { createObservable } from './internals'

const wellKnownSymbols = new Set(
Object.getOwnPropertyNames(Symbol)
.reduce((buf: Symbol[], key) => {
if (key === 'arguments' || key === 'caller') return buf
const value = Symbol[key]
if (typeof value === 'symbol') return buf.concat(value)
return buf
}, [])
Object.getOwnPropertyNames(Symbol).reduce((buf: Symbol[], key) => {
if (key === 'arguments' || key === 'caller') return buf
const value = Symbol[key]
if (typeof value === 'symbol') return buf.concat(value)
return buf
}, [])
)

const hasOwnProperty = Object.prototype.hasOwnProperty
Expand Down Expand Up @@ -201,6 +200,11 @@ export const baseHandlers: ProxyHandler<any> = {
return keys
},
set(target, key, value, receiver) {
// vue2中有对数组原型重写,因此需去除此处proxy
if (key === '__proto__') {
target[key] = value
return true
}
const hadKey = hasOwnProperty.call(target, key)
const newValue = createObservable(target, key, value)
const oldValue = target[key]
Expand Down

0 comments on commit c94da3f

Please sign in to comment.