8000 prop watchers should be triggered on reference change only (fix #1683) · Mat-Moo/vue@8def6c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8def6c7

Browse files
committed
prop watchers should be triggered on reference change only (fix vuejs#1683)
1 parent 296ed69 commit 8def6c7

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

src/directives/internal/prop.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ module.exports = {
3131
filters: prop.filters,
3232
// important: props need to be observed on the
3333
// v-for scope if present
34-
scope: this._scope
34+
scope: this._scope,
35+
// only fire callback when reference has changed
36+
refOnly: true
3537
}
3638
)
3739

@@ -49,6 +51,8 @@ module.exports = {
4951
childKey,
5052
function (val) {
5153
parentWatcher.set(val)
54+
}, {
55+
refOnly: true
5256
}
5357
)
5458
})

src/observer/index.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,15 @@ function defineReactive (obj, key, val) {
179179
get: function metaGetter () {
180180
if (Dep.target) {
181181
dep.depend()
182-
if (childOb) {
183-
childOb.dep.depend()
184-
}
185-
if (_.isArray(val)) {
186-
for (var e, i = 0, l = val.length; i < l; i++) {
187-
e = val[i]
188-
e && e.__ob__ && e.__ob__.dep.depend()
182+
if (!Dep.refOnly) {
183+
if (childOb) {
184+
childOb.dep.depend()
185+
}
186+
if (_.isArray(val)) {
187+
for (var e, i = 0, l = val.length; i < l; i++) {
188+
e = val[i]
189+
e && e.__ob__ && e.__ob__.dep.depend()
190+
}
189191
}
190192
}
191193
}

src/watcher.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var uid = 0
2020
* - {Boolean} user
2121
* - {Boolean} sync
2222
* - {Boolean} lazy
23+
* - {Boolean} refOnly
2324
* - {Function} [preProcess]
2425
* - {Function} [postProcess]
2526
* @constructor 10000
@@ -179,6 +180,7 @@ Watcher.prototype.set = function (value) {
179180

180181
Watcher.prototype.beforeGet = function () {
181182
Dep.target = this
183+
Dep.refOnly = !!this.refOnly
182184
this.newDeps = Object.create(null)
183185
}
184186

@@ -188,6 +190,7 @@ Watcher.prototype.beforeGet = function () {
188190

189191
Watcher.prototype.afterGet = function () {
190192
Dep.target = null
193+
Dep.refOnly = false
191194
var ids = Object.keys(this.deps)
192195
var i = ids.length
193196
while (i--) {

test/unit/specs/directives/internal/prop_spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,5 +550,29 @@ if (_.inBrowser) {
550550
})
551551
expect(_.warn).not.toHaveBeenCalled()
552552
})
553+
554+
// #1683
555+
it('should only trigger sync on reference change', function (done) {
556+
var vm = new Vue({
557+
el: el,
558+
data: {
559+
items: [1, 2]
560+
},
561+
template: '<comp :items.sync="items"></comp>',
562+
components: {
563+
comp: {
564+
props: ['items']
565+
}
566+
}
567+
})
568+
var child = vm.$children[0]
569+
child.items.push(3) // this should not trigger parent to sync it down
570+
var newArray = child.items = [4]
571+
_.nextTick(function () {
572+
expect(child.items).toBe(newArray)
573+
expect(vm.items).toBe(newArray)
574+
done()
575+
})
576+
})
553577
})
554578
}

0 commit comments

Comments
 (0)
0