Jelajahi Sumber

only collect deps for static path getters once

Evan You 11 tahun lalu
induk
melakukan
33da958ed1
3 mengubah file dengan 24 tambahan dan 12 penghapusan
  1. 5 4
      src/parse/expression.js
  2. 1 1
      src/util/merge-option.js
  3. 18 7
      src/watcher.js

+ 5 - 4
src/parse/expression.js

@@ -119,10 +119,11 @@ function compileExpFns (exp, needSet) {
   var getter = makeGetter(body)
   if (getter) {
     return {
-      get   : getter,
-      body  : body,
-      paths : paths,
-      set   : needSet
+      computed : true,
+      get      : getter,
+      body     : body,
+      paths    : paths,
+      set      : needSet
         ? makeSetter(body)
         : null
     }

+ 1 - 1
src/util/merge-option.js

@@ -131,7 +131,7 @@ function guardComponents (components) {
  *                     an instantiation merge.
  */
 
-module.exports = function (parent, child, vm) {
+module.exports = function mergeOptions (parent, child, vm) {
   guardComponents(child.components)
   var options = {}
   var key

+ 18 - 7
src/watcher.js

@@ -41,7 +41,7 @@ function Watcher (vm, expression, cb, ctx, filters, needSet) {
   res = expParser.parse(expression, needSet)
   this.getter = res.get
   this.setter = res.set
-  this.initDeps(res.paths)
+  this.initDeps(res)
 }
 
 var p = Watcher.prototype
@@ -58,15 +58,22 @@ var p = Watcher.prototype
  * the directive will end up with no dependency at all and
  * never gets updated.
  *
- * @param {Array} paths
+ * @param {Object} res - expression parser result object
  */
 
-p.initDeps = function (paths) {
-  var i = paths.length
+p.initDeps = function (res) {
+  var i = res.paths.length
   while (i--) {
-    this.addDep(paths[i])
+    this.addDep(res.paths[i])
   }
+  // temporarily set computed to true
+  // to force dep collection on first evaluation
+  this.isComputed = true
   this.value = this.get()
+  var computed = this.vm.$options.computed
+  this.isComputed =
+    res.computed || // inline expression
+    (computed && computed[expression]) // computed property
 }
 
 /**
@@ -95,10 +102,14 @@ p.addDep = function (path) {
  */
 
 p.get = function () {
-  this.beforeGet()
+  if (this.isComputed) {
+    this.beforeGet()
+  }
   var value = this.getter.call(this.vm, this.vm.$scope)
   value = _.applyFilters(value, this.readFilters, this.vm)
-  this.afterGet()
+  if (this.isComputed) {
+    this.afterGet()
+  }
   return value
 }