Просмотр исходного кода

Custom Directive API improvements

- `isLiteral`, `isEmpty` and `isFn` are now explicit options.
- bind() now get the initial value as the argument.
Evan You 12 лет назад
Родитель
Сommit
89d32e5e41
4 измененных файлов с 30 добавлено и 16 удалено
  1. 4 4
      src/compiler.js
  2. 2 2
      src/directive.js
  3. 1 0
      src/directives/index.js
  4. 23 10
      test/unit/specs/api.js

+ 4 - 4
src/compiler.js

@@ -503,7 +503,7 @@ CompilerProto.bindDirective = function (directive) {
 
     // for empty or literal directives, simply call its bind()
     // and we're done.
-    if (directive.isEmpty || !directive._update) {
+    if (directive.isEmpty || directive.isLiteral) {
         if (directive.bind) directive.bind()
         return
     }
@@ -531,13 +531,13 @@ CompilerProto.bindDirective = function (directive) {
     binding.dirs.push(directive)
     directive.binding = binding
 
+    var value = binding.val()
     // invoke bind hook if exists
     if (directive.bind) {
-        directive.bind()
+        directive.bind(value)
     }
-
     // set initial value
-    directive.update(binding.val(), true)
+    directive.update(value, true)
 }
 
 /**

+ 2 - 2
src/directive.js

@@ -27,7 +27,7 @@ function Directive (definition, expression, rawKey, compiler, node) {
     this.vm       = compiler.vm
     this.el       = node
 
-    var isEmpty  = expression === ''
+    var isEmpty   = expression === ''
 
     // mix in properties from the directive definition
     if (typeof definition === 'function') {
@@ -43,7 +43,7 @@ function Directive (definition, expression, rawKey, compiler, node) {
     }
 
     // empty expression, we're done.
-    if (isEmpty) {
+    if (isEmpty || this.isEmpty) {
         this.isEmpty = true
         return
     }

+ 1 - 0
src/directives/index.js

@@ -48,6 +48,7 @@ module.exports = {
     },
 
     cloak: {
+        isEmpty: true,
         bind: function () {
             var el = this.el
             this.compiler.observer.once('hook:ready', function () {

+ 23 - 10
test/unit/specs/api.js

@@ -150,8 +150,8 @@ describe('UNIT: API', function () {
             var testId = 'directive-2',
                 msg = 'wowaaaa?'
             dirTest = {
-                bind: function () {
-                    this.el.setAttribute(testId + 'bind', 'bind')
+                bind: function (value) {
+                    this.el.setAttribute(testId + 'bind', value + 'bind')
                 },
                 update: function (value) {
                     this.el.setAttribute(testId + 'update', value + 'update')
@@ -167,25 +167,38 @@ describe('UNIT: API', function () {
                     data: { test: msg }
                 }),
                 el = document.querySelector('#' + testId + ' span')
-            assert.strictEqual(el.getAttribute(testId + 'bind'), 'bind', 'should have called bind()')
-            assert.strictEqual(el.getAttribute(testId + 'update'), msg + 'update', 'should have called update()')
+            assert.strictEqual(el.getAttribute(testId + 'bind'), msg + 'bind', 'should have called bind() with value')
+            assert.strictEqual(el.getAttribute(testId + 'update'), msg + 'update', 'should have called update() with value')
             vm.$destroy() // assuming this works
             assert.notOk(el.getAttribute(testId + 'bind'), 'should have called unbind()')
         })
 
-        it('should not bind directive if no update() is provided', function () {
-            var called = false
+        it('should not create binding for literal or empty directives', function () {
+            var literalCalled = false,
+                emptyCalled = false
             Vue.directive('test-literal', {
+                isLiteral: true,
                 bind: function () {
-                    called = true
+                    literalCalled = true
                     assert.strictEqual(this.expression, 'hihi')
                     assert.notOk(this.binding)
-                }
+                },
+                update: function () {}
+            })
+            Vue.directive('test-empty', {
+                isEmpty: true,
+                bind: function () {
+                    emptyCalled = true
+                    assert.notOk(this.expression)
+                    assert.notOk(this.binding)
+                },
+                update: function () {}
             })
             new Vue({
-                template: '<div v-test-literal="hihi"></div>'
+                template: '<div v-test-literal="hihi"></div><div v-test-empty="123"></div>'
             })
-            assert.ok(called)
+            assert.ok(literalCalled)
+            assert.ok(emptyCalled)
         })
 
         it('should return directive object/fn if only one arg is given', function () {