Przeglądaj źródła

a more proper fix for #1683

Evan You 10 lat temu
rodzic
commit
ee5f458ca5

+ 5 - 4
src/directives/internal/prop.js

@@ -31,9 +31,7 @@ module.exports = {
         filters: prop.filters,
         filters: prop.filters,
         // important: props need to be observed on the
         // important: props need to be observed on the
         // v-for scope if present
         // v-for scope if present
-        scope: this._scope,
-        // only fire callback when reference has changed
-        refOnly: true
+        scope: this._scope
       }
       }
     )
     )
 
 
@@ -52,7 +50,10 @@ module.exports = {
           function (val) {
           function (val) {
             parentWatcher.set(val)
             parentWatcher.set(val)
           }, {
           }, {
-            refOnly: true
+            // ensure sync upward before parent sync down.
+            // this is necessary in cases e.g. the child
+            // mutates a prop array, then replaces it. (#1683)
+            sync: true
           }
           }
         )
         )
       })
       })

+ 7 - 9
src/observer/index.js

@@ -179,15 +179,13 @@ function defineReactive (obj, key, val) {
     get: function metaGetter () {
     get: function metaGetter () {
       if (Dep.target) {
       if (Dep.target) {
         dep.depend()
         dep.depend()
-        if (!Dep.refOnly) {
-          if (childOb) {
-            childOb.dep.depend()
-          }
-          if (_.isArray(val)) {
-            for (var e, i = 0, l = val.length; i < l; i++) {
-              e = val[i]
-              e && e.__ob__ && e.__ob__.dep.depend()
-            }
+        if (childOb) {
+          childOb.dep.depend()
+        }
+        if (_.isArray(val)) {
+          for (var e, i = 0, l = val.length; i < l; i++) {
+            e = val[i]
+            e && e.__ob__ && e.__ob__.dep.depend()
           }
           }
         }
         }
       }
       }

+ 0 - 3
src/watcher.js

@@ -20,7 +20,6 @@ var uid = 0
  *                 - {Boolean} user
  *                 - {Boolean} user
  *                 - {Boolean} sync
  *                 - {Boolean} sync
  *                 - {Boolean} lazy
  *                 - {Boolean} lazy
- *                 - {Boolean} refOnly
  *                 - {Function} [preProcess]
  *                 - {Function} [preProcess]
  *                 - {Function} [postProcess]
  *                 - {Function} [postProcess]
  * @constructor
  * @constructor
@@ -180,7 +179,6 @@ Watcher.prototype.set = function (value) {
 
 
 Watcher.prototype.beforeGet = function () {
 Watcher.prototype.beforeGet = function () {
   Dep.target = this
   Dep.target = this
-  Dep.refOnly = !!this.refOnly
   this.newDeps = Object.create(null)
   this.newDeps = Object.create(null)
 }
 }
 
 
@@ -190,7 +188,6 @@ Watcher.prototype.beforeGet = function () {
 
 
 Watcher.prototype.afterGet = function () {
 Watcher.prototype.afterGet = function () {
   Dep.target = null
   Dep.target = null
-  Dep.refOnly = false
   var ids = Object.keys(this.deps)
   var ids = Object.keys(this.deps)
   var i = ids.length
   var i = ids.length
   while (i--) {
   while (i--) {

+ 2 - 2
test/unit/specs/directives/internal/prop_spec.js

@@ -552,7 +552,7 @@ if (_.inBrowser) {
     })
     })
 
 
     // #1683
     // #1683
-    it('should only trigger sync on reference change', function (done) {
+    it('should properly sync back up when mutating then replace', function (done) {
       var vm = new Vue({
       var vm = new Vue({
         el: el,
         el: el,
         data: {
         data: {
@@ -566,7 +566,7 @@ if (_.inBrowser) {
         }
         }
       })
       })
       var child = vm.$children[0]
       var child = vm.$children[0]
-      child.items.push(3) // this should not trigger parent to sync it down
+      child.items.push(3)
       var newArray = child.items = [4]
       var newArray = child.items = [4]
       _.nextTick(function () {
       _.nextTick(function () {
         expect(child.items).toBe(newArray)
         expect(child.items).toBe(newArray)