Browse Source

avoid syncing data when possible

Evan You 11 years ago
parent
commit
89a64ea545
5 changed files with 25 additions and 8 deletions
  1. 2 1
      src/directives/component.js
  2. 2 1
      src/directives/if.js
  3. 2 1
      src/directives/repeat.js
  4. 7 0
      src/directives/with.js
  5. 12 5
      src/instance/scope.js

+ 2 - 1
src/directives/component.js

@@ -134,7 +134,8 @@ module.exports = {
     if (this.Ctor && !this.childVM) {
       this.childVM = new this.Ctor({
         el: this.el.cloneNode(true),
-        parent: this.vm
+        parent: this.vm,
+        _noSync: true
       })
       if (this.keepAlive) {
         this.cache[this.id] = this.childVM

+ 2 - 1
src/directives/if.js

@@ -41,7 +41,8 @@ module.exports = {
     this.childVM = new _.Vue({
       el: this.el,
       parent: this.vm,
-      anonymous: true
+      anonymous: true,
+      _noSync: true
     })
   },
 

+ 2 - 1
src/directives/repeat.js

@@ -240,7 +240,8 @@ module.exports = {
     var vm = new Ctor({
       el: this.el.cloneNode(true),
       data: data,
-      parent: this.vm
+      parent: this.vm,
+      _noSync: hasAlias
     })
     // define alias
     if (hasAlias && !alias) {

+ 7 - 0
src/directives/with.js

@@ -5,6 +5,13 @@ module.exports = {
   priority: 900,
 
   bind: function () {
+    if (!this.arg) {
+      // by default, components have _noSync:true
+      // but when there's no arg it means we are
+      // inheriting a parent object as $data, so we have
+      // to sync the chagnes
+      this.vm.$options._noSync = false
+    }
     var self = this
     var path = this.arg || '$data'
     this.vm.$watch(path, function (val) {

+ 12 - 5
src/instance/scope.js

@@ -69,6 +69,7 @@ exports._teardownScope = function () {
     scopeEvents.forEach(function (event) {
       pob.off(event, listeners[event])
     })
+    this._scopeListeners = null
   }
 }
 
@@ -84,10 +85,14 @@ exports._teardownScope = function () {
  */
 
 exports._setData = function (data) {
+  this._data = data
   var scope = this.$scope
+  var noSync = this.$options._noSync
   var key
   // teardown old sync listeners
-  this._unsyncData()
+  if (!noSync) {
+    this._unsyncData()
+  }
   // delete keys not present in the new data
   for (key in scope) {
     if (
@@ -109,8 +114,9 @@ exports._setData = function (data) {
     }
   }
   // setup sync between scope and new data
-  this._data = data
-  this._syncData()
+  if (!noSync) {
+    this._syncData()
+  }
 }
 
 /**
@@ -281,12 +287,13 @@ exports._syncData = function () {
 
 exports._unsyncData = function () {
   var listeners = this._syncListeners
-
+  if (!listeners) {
+    return
+  }
   this.$observer
     .off('set:self', listeners.data.set)
     .off('add:self', listeners.data.add)
     .off('delete:self', listeners.data.delete)
-
   this._dataObserver
     .off('set:self', listeners.scope.set)
     .off('add:self', listeners.scope.add)