فهرست منبع

compile container dirs and props in proper context instead of parent

Evan You 11 سال پیش
والد
کامیت
68bfc66792

+ 20 - 20
src/compiler/compile.js

@@ -94,16 +94,16 @@ function linkAndCapture (linker, vm) {
  *
  * @param {Vue} vm
  * @param {Array} dirs
- * @param {Vue} [parent]
- * @param {Array} [parentDirs]
+ * @param {Vue} [context]
+ * @param {Array} [contextDirs]
  * @return {Function}
  */
 
-function makeUnlinkFn (vm, dirs, parent, parentDirs) {
+function makeUnlinkFn (vm, dirs, context, contextDirs) {
   return function unlink (destroying) {
     teardownDirs(vm, dirs, destroying)
-    if (parent && parentDirs) {
-      teardownDirs(parent, parentDirs)
+    if (context && contextDirs) {
+      teardownDirs(context, contextDirs)
     }
   }
 }
@@ -146,7 +146,7 @@ exports.compileAndLinkProps = function (vm, el, props) {
 /**
  * Compile the root element of an instance.
  *
- * 1. attrs on parent container (parent scope)
+ * 1. attrs on context container (context scope)
  * 2. attrs on the component template root node, if
  *    replace:true (child scope)
  *
@@ -154,7 +154,7 @@ exports.compileAndLinkProps = function (vm, el, props) {
  *
  * This function does compile and link at the same time,
  * since root linkers can not be reused. It returns the
- * unlink function for potential parent directives on the
+ * unlink function for potential context directives on the
  * container.
  *
  * @param {Vue} vm
@@ -166,7 +166,7 @@ exports.compileAndLinkProps = function (vm, el, props) {
  exports.compileAndLinkRoot = function (vm, el, options) {
   var containerAttrs = options._containerAttrs
   var replacerAttrs = options._replacerAttrs
-  var parentLinkFn, replacerLinkFn
+  var contextLinkFn, replacerLinkFn
 
   // only need to compile other attributes for
   // non-block instances
@@ -176,7 +176,7 @@ exports.compileAndLinkProps = function (vm, el, props) {
     if (options._asComponent) {
       // 2. container attributes
       if (containerAttrs) {
-        parentLinkFn = compileDirectives(containerAttrs, options)
+        contextLinkFn = compileDirectives(containerAttrs, options)
       }
       if (replacerAttrs) {
         // 3. replacer attributes
@@ -188,13 +188,13 @@ exports.compileAndLinkProps = function (vm, el, props) {
     }
   }
 
-  // link parent dirs
-  var parent = vm.$parent
-  var parentDirs
-  if (parent && parentLinkFn) {
-    parentDirs = linkAndCapture(function () {
-      parentLinkFn(parent, el)
-    }, parent)
+  // link context scope dirs
+  var context = vm._context
+  var contextDirs
+  if (context && contextLinkFn) {
+    contextDirs = linkAndCapture(function () {
+      contextLinkFn(context, el)
+    }, context)
   }
 
   // link self
@@ -202,9 +202,9 @@ exports.compileAndLinkProps = function (vm, el, props) {
     if (replacerLinkFn) replacerLinkFn(vm, el)
   }, vm)
 
-  // return the unlink function that tearsdown parent
+  // return the unlink function that tearsdown context
   // container directives.
-  return makeUnlinkFn(vm, selfDirs, parent, parentDirs)
+  return makeUnlinkFn(vm, selfDirs, context, contextDirs)
 }
 
 /**
@@ -522,10 +522,10 @@ function makePropsLinkFn (props) {
         vm._data[path] = undefined
       } else if (prop.dynamic) {
         // dynamic prop
-        if (vm.$parent) {
+        if (vm._context) {
           if (prop.mode === propBindingModes.ONE_TIME) {
             // one time binding
-            value = vm.$parent.$get(prop.parentPath)
+            value = vm._context.$get(prop.parentPath)
             if (_.assertProp(prop, value)) {
               vm[path] = vm._data[path] = value
             }

+ 1 - 1
src/directives/component.js

@@ -178,7 +178,7 @@ module.exports = {
         _linkerCachable: !this.template,
         _asComponent: true,
         _isRouterView: this._isRouterView,
-        _contentOwner: this.vm
+        _context: this.vm
       }, this.Ctor)
       if (this.keepAlive) {
         this.cache[this.ctorId] = child

+ 1 - 1
src/directives/prop.js

@@ -12,7 +12,7 @@ module.exports = {
   bind: function () {
 
     var child = this.vm
-    var parent = child.$parent
+    var parent = child._context
     // passed in from compiler directly
     var prop = this._descriptor
     var childKey = prop.path

+ 1 - 1
src/directives/repeat.js

@@ -365,7 +365,7 @@ module.exports = {
       // identifier, shows that this vm belongs to this collection
       _repeatId: this.id,
       // transclusion content owner
-      _contentOwner: this.vm
+      _context: this.vm
     }, Ctor)
     // cache instance
     if (needCache) {

+ 8 - 10
src/element-directives/content.js

@@ -10,8 +10,8 @@ module.exports = {
   bind: function () {
     var vm = this.vm
     var host = vm
-    // we need find the content owner, which is the closest
-    // non-inline-repeater instance.
+    // we need find the content context, which is the
+    // closest non-inline-repeater instance.
     while (host.$options._repeat) {
       host = host.$parent
     }
@@ -21,9 +21,7 @@ module.exports = {
       this.fallback()
       return
     }
-    var owner =
-      host.$options._contentOwner ||
-      host.$parent
+    var context = host._context
     var selector = this.el.getAttribute('select')
     if (!selector) {
       // Default content
@@ -31,7 +29,7 @@ module.exports = {
       var compileDefaultContent = function () {
         self.compile(
           extractFragment(raw.childNodes, raw, true),
-          owner,
+          context,
           vm
         )
       }
@@ -51,7 +49,7 @@ module.exports = {
       if (nodes.length) {
         content = extractFragment(nodes, raw)
         if (content.hasChildNodes()) {
-          this.compile(content, owner, vm)
+          this.compile(content, context, vm)
         } else {
           this.fallback()
         }
@@ -65,9 +63,9 @@ module.exports = {
     this.compile(_.extractContent(this.el, true), this.vm)
   },
 
-  compile: function (content, owner, host) {
-    if (content && owner) {
-      this.unlink = owner.$compile(content, host)
+  compile: function (content, context, host) {
+    if (content && context) {
+      this.unlink = context.$compile(content, host)
     }
     if (content) {
       _.replace(this.el, content)

+ 8 - 3
src/instance/init.js

@@ -18,10 +18,12 @@ exports._init = function (options) {
   this.$el           = null
   this.$parent       = options._parent
   this.$root         = options._root || this
+  this.$children     = []
   this.$             = {} // child vm references
   this.$$            = {} // element references
   this._watchers     = [] // all watchers as an array
   this._directives   = [] // all directives
+  this._childCtors   = {} // inherit:true constructors
 
   // a flag to avoid this being observed
   this._isVue = true
@@ -44,9 +46,12 @@ exports._init = function (options) {
   this._isBeingDestroyed = false
   this._unlinkFn    = null
 
-  // children
-  this.$children = []
-  this._childCtors = {}
+  // context: the scope in which the component was used,
+  // and the scope in which props and contents of this
+  // instance should be compiled in.
+  this._context =
+    options._context ||
+    options._parent
 
   // push self into parent / transclusion host
   if (this.$parent) {

+ 4 - 4
test/unit/specs/compiler/compile_spec.js

@@ -30,7 +30,7 @@ if (_.inBrowser) {
         $interpolate: function (value) {
           return data[value]
         },
-        $parent: {
+        _context: {
           _directives: [],
           $get: function (v) {
             return 'from parent: ' + v
@@ -220,8 +220,8 @@ if (_.inBrowser) {
 
     it('props on root instance', function () {
       // temporarily remove vm.$parent
-      var parent = vm.$parent
-      vm.$parent = null
+      var context = vm._context
+      vm._context = null
       var def = Vue.options.directives._prop
       el.setAttribute('a', 'hi')
       el.setAttribute('b', '{{hi}}')
@@ -230,7 +230,7 @@ if (_.inBrowser) {
       expect(vm._data.a).toBe('hi')
       expect(hasWarned(_, 'Cannot bind dynamic prop on a root')).toBe(true)
       // restore parent mock
-      vm.$parent = parent
+      vm._context = context
     })
 
     it('DocumentFragment', function () {