mirror of https://github.com/vuejs/core.git
fix(reactivity): fix mutation on user proxy of reactive Array
close #9742 close #9751 close #9750
This commit is contained in:
parent
983d45d4f8
commit
6ecbd5ce2a
|
|
@ -158,6 +158,21 @@ describe('reactivity/reactive', () => {
|
||||||
expect(original.bar).toBe(original2)
|
expect(original.bar).toBe(original2)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #1246
|
||||||
|
test('mutation on objects using reactive as prototype should not trigger', () => {
|
||||||
|
const observed = reactive({ foo: 1 })
|
||||||
|
const original = Object.create(observed)
|
||||||
|
let dummy
|
||||||
|
effect(() => (dummy = original.foo))
|
||||||
|
expect(dummy).toBe(1)
|
||||||
|
observed.foo = 2
|
||||||
|
expect(dummy).toBe(2)
|
||||||
|
original.foo = 3
|
||||||
|
expect(dummy).toBe(2)
|
||||||
|
original.foo = 4
|
||||||
|
expect(dummy).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
test('toRaw', () => {
|
test('toRaw', () => {
|
||||||
const original = { foo: 1 }
|
const original = { foo: 1 }
|
||||||
const observed = reactive(original)
|
const observed = reactive(original)
|
||||||
|
|
@ -166,11 +181,18 @@ describe('reactivity/reactive', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('toRaw on object using reactive as prototype', () => {
|
test('toRaw on object using reactive as prototype', () => {
|
||||||
const original = reactive({})
|
const original = { foo: 1 }
|
||||||
const obj = Object.create(original)
|
const observed = reactive(original)
|
||||||
|
const inherted = Object.create(observed)
|
||||||
|
expect(toRaw(inherted)).toBe(inherted)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('toRaw on user Proxy wrapping reactive', () => {
|
||||||
|
const original = {}
|
||||||
|
const re = reactive(original)
|
||||||
|
const obj = new Proxy(re, {})
|
||||||
const raw = toRaw(obj)
|
const raw = toRaw(obj)
|
||||||
expect(raw).toBe(obj)
|
expect(raw).toBe(original)
|
||||||
expect(raw).not.toBe(toRaw(original))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should not unwrap Ref<T>', () => {
|
test('should not unwrap Ref<T>', () => {
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,15 @@ describe('reactivity/reactive/Array', () => {
|
||||||
expect(length).toBe('01')
|
expect(length).toBe('01')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #9742
|
||||||
|
test('mutation on user proxy of reactive Array', () => {
|
||||||
|
const array = reactive<number[]>([])
|
||||||
|
const proxy = new Proxy(array, {})
|
||||||
|
proxy.push(1)
|
||||||
|
expect(array).toHaveLength(1)
|
||||||
|
expect(proxy).toHaveLength(1)
|
||||||
|
})
|
||||||
|
|
||||||
describe('Array methods w/ refs', () => {
|
describe('Array methods w/ refs', () => {
|
||||||
let original: any[]
|
let original: any[]
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@ class BaseReactiveHandler implements ProxyHandler<Target> {
|
||||||
return isReadonly
|
return isReadonly
|
||||||
} else if (key === ReactiveFlags.IS_SHALLOW) {
|
} else if (key === ReactiveFlags.IS_SHALLOW) {
|
||||||
return shallow
|
return shallow
|
||||||
} else if (
|
} else if (key === ReactiveFlags.RAW) {
|
||||||
key === ReactiveFlags.RAW &&
|
if (
|
||||||
receiver ===
|
receiver ===
|
||||||
(isReadonly
|
(isReadonly
|
||||||
? shallow
|
? shallow
|
||||||
|
|
@ -110,10 +110,16 @@ class BaseReactiveHandler implements ProxyHandler<Target> {
|
||||||
: shallow
|
: shallow
|
||||||
? shallowReactiveMap
|
? shallowReactiveMap
|
||||||
: reactiveMap
|
: reactiveMap
|
||||||
).get(target)
|
).get(target) ||
|
||||||
|
// receiver is not the reactive proxy, but has the same prototype
|
||||||
|
// this means the reciever is a user proxy of the reactive proxy
|
||||||
|
Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)
|
||||||
) {
|
) {
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
// early return undefined
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const targetIsArray = isArray(target)
|
const targetIsArray = isArray(target)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue