mirror of https://github.com/vuejs/vue.git
Added support for properties which were created with defineProperty outside of vue
This commit is contained in:
parent
6ce6e0c995
commit
0b1be55c04
|
|
@ -172,7 +172,11 @@ function copyAugment (target, src, keys) {
|
|||
|
||||
function defineReactive (obj, key, val) {
|
||||
var dep = new Dep()
|
||||
var childOb = Observer.create(val)
|
||||
|
||||
var property = Object.getOwnPropertyDescriptor(obj, key)
|
||||
var getter = (property && property.get) || function () { return val }
|
||||
var setter = (property && property.set) || function (v) { val = v }
|
||||
var childOb = Observer.create(getter())
|
||||
Object.defineProperty(obj, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
|
|
@ -182,18 +186,18 @@ function defineReactive (obj, key, val) {
|
|||
if (childOb) {
|
||||
childOb.dep.depend()
|
||||
}
|
||||
if (_.isArray(val)) {
|
||||
for (var e, i = 0, l = val.length; i < l; i++) {
|
||||
e = val[i]
|
||||
if (_.isArray(getter())) {
|
||||
for (var e, i = 0, l = getter().length; i < l; i++) {
|
||||
e = getter()[i]
|
||||
e && e.__ob__ && e.__ob__.dep.depend()
|
||||
}
|
||||
}
|
||||
}
|
||||
return val
|
||||
return getter()
|
||||
},
|
||||
set: function metaSetter (newVal) {
|
||||
if (newVal === val) return
|
||||
val = newVal
|
||||
if (newVal === getter()) return
|
||||
setter(newVal)
|
||||
childOb = Observer.create(newVal)
|
||||
dep.notify()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,35 @@ describe('Observer', function () {
|
|||
expect(ob2).toBe(ob)
|
||||
})
|
||||
|
||||
it('create on already observed object', function () {
|
||||
// on object
|
||||
var obj = {}
|
||||
var val = 0
|
||||
Object.defineProperty(obj, 'a', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return val
|
||||
},
|
||||
set: function (v) {
|
||||
val = v
|
||||
}
|
||||
})
|
||||
|
||||
var ob = Observer.create(obj)
|
||||
expect(ob instanceof Observer).toBe(true)
|
||||
expect(ob.value).toBe(obj)
|
||||
expect(obj.__ob__).toBe(ob)
|
||||
|
||||
// should return existing ob on already observed objects
|
||||
var ob2 = Observer.create(obj)
|
||||
expect(ob2).toBe(ob)
|
||||
|
||||
// should call underlying setter
|
||||
obj.a = 10
|
||||
expect(val).toBe(10)
|
||||
})
|
||||
|
||||
it('create on array', function () {
|
||||
// on object
|
||||
var arr = [{}, {}]
|
||||
|
|
@ -82,6 +111,50 @@ describe('Observer', function () {
|
|||
expect(watcher.update.calls.count()).toBe(3)
|
||||
})
|
||||
|
||||
it('observing object prop change on defined property', function () {
|
||||
var obj = { }
|
||||
var val = { b: 2 }
|
||||
Object.defineProperty(obj, 'a', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return val
|
||||
},
|
||||
set: function (v) {
|
||||
val = v
|
||||
}
|
||||
})
|
||||
|
||||
Observer.create(obj)
|
||||
// mock a watcher!
|
||||
var watcher = {
|
||||
deps: [],
|
||||
addDep: function (dep) {
|
||||
this.deps.push(dep)
|
||||
dep.addSub(this)
|
||||
},
|
||||
update: jasmine.createSpy()
|
||||
}
|
||||
// collect dep
|
||||
Dep.target = watcher
|
||||
obj.a.b
|
||||
Dep.target = null
|
||||
expect(watcher.deps.length).toBe(3) // obj.a + a.b + b
|
||||
obj.a.b = 3
|
||||
expect(watcher.update.calls.count()).toBe(1)
|
||||
// swap object
|
||||
obj.a = { b: 4 }
|
||||
expect(watcher.update.calls.count()).toBe(2)
|
||||
watcher.deps = []
|
||||
Dep.target = watcher
|
||||
obj.a.b
|
||||
Dep.target = null
|
||||
expect(watcher.deps.length).toBe(3)
|
||||
// set on the swapped object
|
||||
obj.a.b = 5
|
||||
expect(watcher.update.calls.count()).toBe(3)
|
||||
})
|
||||
|
||||
it('observing set/delete', function () {
|
||||
var obj = { a: 1 }
|
||||
var ob = Observer.create(obj)
|
||||
|
|
|
|||
Loading…
Reference in New Issue