소스 검색

fix: compile container directives in correct context (fix #1442)

Evan You 10 년 전
부모
커밋
9c45702c65
3개의 변경된 파일23개의 추가작업 그리고 4개의 파일을 삭제
  1. 4 3
      src/compiler/compile.js
  2. 2 1
      src/instance/lifecycle.js
  3. 17 0
      test/unit/specs/compiler/compile_spec.js

+ 4 - 3
src/compiler/compile.js

@@ -179,10 +179,11 @@ exports.compileAndLinkProps = function (vm, el, props, scope) {
  * @param {Vue} vm
  * @param {Element} el
  * @param {Object} options
+ * @param {Object} contextOptions
  * @return {Function}
  */
 
-exports.compileRoot = function (el, options) {
+exports.compileRoot = function (el, options, contextOptions) {
   var containerAttrs = options._containerAttrs
   var replacerAttrs = options._replacerAttrs
   var contextLinkFn, replacerLinkFn
@@ -194,8 +195,8 @@ exports.compileRoot = function (el, options) {
     // compiled separately and linked in different scopes.
     if (options._asComponent) {
       // 2. container attributes
-      if (containerAttrs) {
-        contextLinkFn = compileDirectives(containerAttrs, options)
+      if (containerAttrs && contextOptions) {
+        contextLinkFn = compileDirectives(containerAttrs, contextOptions)
       }
       if (replacerAttrs) {
         // 3. replacer attributes

+ 2 - 1
src/instance/lifecycle.js

@@ -29,7 +29,8 @@ exports._compile = function (el) {
 
   // root is always compiled per-instance, because
   // container attrs and props can be different every time.
-  var rootLinker = compiler.compileRoot(el, options)
+  var contextOptions = this._context && this._context.$options
+  var rootLinker = compiler.compileRoot(el, options, contextOptions)
 
   // compile and link the rest
   var contentLinkFn

+ 17 - 0
test/unit/specs/compiler/compile_spec.js

@@ -528,5 +528,22 @@ if (_.inBrowser) {
       expect(hasWarned(_, 'v-show is ignored on component <test>')).toBe(true)
     })
 
+    it('should compile component container directives using correct context', function () {
+      new Vue({
+        el: el,
+        directives: {
+          test: {
+            bind: function () {
+              this.el.textContent = 'worked!'
+            }
+          }
+        },
+        template: '<comp v-test></comp>',
+        components: { comp: { template: '<div></div>'}}
+      })
+      expect(el.textContent).toBe('worked!')
+      expect(_.warn).not.toHaveBeenCalled()
+    })
+
   })
 }