Skip to content

Commit 56ec4b4

Browse files
fix(traverse): Prevent traversing Vue instances
Related: vuejs/vuex#1587
1 parent d40b7dd commit 56ec4b4

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/core/observer/traverse.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import { _Set as Set, isObject } from '../util/index'
44
import type { SimpleSet } from '../util/index'
55
import VNode from '../vdom/vnode'
6+
import Vue from '../instance/index'
7+
68

79
const seenObjects = new Set()
810

@@ -19,7 +21,7 @@ export function traverse (val: any) {
1921
function _traverse (val: any, seen: SimpleSet) {
2022
let i, keys
2123
const isA = Array.isArray(val)
22-
if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) {
24+
if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode || val instanceof Vue) {
2325
return
2426
}
2527
if (val.__ob__) {

test/unit/features/options/watch.spec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,29 @@ describe('Options watch', () => {
106106
}).then(done)
107107
})
108108

109+
it('with option: deep and with reference to a Vue instance', done => {
110+
const vueInstance = new Vue();
111+
const vm = new Vue({
112+
data: { a: { b: vueInstance }},
113+
watch: {
114+
a: {
115+
handler: spy,
116+
deep: true
117+
}
118+
}
119+
})
120+
const oldA = vm.a
121+
expect(spy).not.toHaveBeenCalled()
122+
vm.a.b = 2
123+
expect(spy).not.toHaveBeenCalled()
124+
waitForUpdate(() => {
125+
expect(spy).toHaveBeenCalledWith(vm.a, vm.a)
126+
vm.a = { b: 3 }
127+
}).then(() => {
128+
expect(spy).toHaveBeenCalledWith(vm.a, oldA)
129+
}).then(done)
130+
})
131+
109132
it('correctly merges multiple extends', done => {
110133
const spy2 = jasmine.createSpy('A')
111134
const spy3 = jasmine.createSpy('B')

0 commit comments

Comments
 (0)