Sfoglia il codice sorgente

enable $event in v-on expressions + enable e.preventDefault()

Evan You 12 anni fa
parent
commit
1b1d72ea56

+ 3 - 1
src/compiler.js

@@ -76,6 +76,7 @@ function Compiler (vm, options) {
     def(vm, '$el', el)
     def(vm, '$options', options)
     def(vm, '$compiler', compiler)
+    def(vm, '$event', null, false, true)
 
     // set parent
     var parentVM = options.parent
@@ -783,7 +784,8 @@ CompilerProto.addDelegator = function (event) {
             }
         }
     }
-    this.el.addEventListener(event, delegator.handler)
+    // useCapture:true so e.preventDefault() works
+    this.el.addEventListener(event, delegator.handler, true)
     return delegator
 }
 

+ 6 - 3
src/directives/on.js

@@ -21,12 +21,15 @@ module.exports = {
         }
         var el       = this.el,
             targetVM = this.vm,
-            ownerVM  = this.binding.compiler.vm,
-            isExp    = this.binding.isExp,
+            context  = this.binding.isExp
+                ? targetVM
+                : this.binding.compiler.vm,
             newHandler = function (e) {
                 e.targetEl = el
                 e.targetVM = targetVM
-                handler.call(isExp ? targetVM : ownerVM, e)
+                context.$event = e
+                handler.call(context, e)
+                context.$event = null
             }
         if (!this.bubbles) {
             this.reset()

+ 2 - 1
src/utils.js

@@ -79,11 +79,12 @@ var utils = module.exports = {
      *  This avoids it being included in JSON.stringify
      *  or for...in loops.
      */
-    defProtected: function (obj, key, val, enumerable) {
+    defProtected: function (obj, key, val, enumerable, writable) {
         if (obj.hasOwnProperty(key)) return
         Object.defineProperty(obj, key, {
             value        : val,
             enumerable   : !!enumerable,
+            writable     : !!writable,
             configurable : true
         })
     },

+ 14 - 2
test/functional/fixtures/animation.html

@@ -4,54 +4,66 @@
         display: inline-block;
     }
     .v-enter {
-        -webkit-animation: fadein .2s;
         animation: fadein .2s;
+        -webkit-animation: fadein .2s;
     }
     .v-leave {
-        -webkit-animation: fadeout .2s;
         animation: fadeout .2s;
+        -webkit-animation: fadeout .2s;
     }
     @keyframes fadein {
         0% {
+            -webkit-transform: scale(0);
             transform: scale(0);
         }
         50% {
+            -webkit-transform: scale(1.5);
             transform: scale(1.5);
         }
         100% {
+            -webkit-transform: scale(1);
             transform: scale(1);
         }
     }
     @keyframes fadeout {
         0% {
             transform: scale(1);
+            -webkit-transform: scale(1);
         }
         50% {
             transform: scale(1.5);
+            -webkit-transform: scale(1.5);
         }
         100% {
             transform: scale(0);
+            -webkit-transform: scale(0);
         }
     }
     @-webkit-keyframes fadein {
         0% {
             -webkit-transform: scale(0);
+            transform: scale(0);
         }
         50% {
             -webkit-transform: scale(1.5);
+            transform: scale(1.5);
         }
         100% {
             -webkit-transform: scale(1);
+            transform: scale(1);
         }
     }
     @-webkit-keyframes fadeout {
         0% {
+            transform: scale(1);
             -webkit-transform: scale(1);
         }
         50% {
+            transform: scale(1.5);
             -webkit-transform: scale(1.5);
         }
         100% {
+            transform: scale(0);
             -webkit-transform: scale(0);
         }
     }

+ 27 - 0
test/functional/fixtures/events.html

@@ -0,0 +1,27 @@
+<script src="../../../dist/vue.js"></script>
+
+<div v-on="click:outer">
+    <p class="outer" v-show="outerTriggered">Outer triggered</p>
+    <p class="msg">{{msg}}</p>
+    <a class="normal" v-on="click:normal">normal</a>
+    <a class="exp" href="#triggered" v-on="click:exp('hello', $event)">exp</a>
+</div>
+
+<script>
+var test = new Vue({
+    el: 'div',
+    methods: {
+        outer: function () {
+            this.outerTriggered = true
+        },
+        normal: function (e) {
+            e.stopPropagation()
+        },
+        exp: function (msg, e) {
+            this.msg = msg
+            e.stopPropagation()
+            e.preventDefault()
+        }
+    }
+})
+</script>

+ 26 - 0
test/functional/specs/events.js

@@ -0,0 +1,26 @@
+casper.test.begin('Events', 5, function (test) {
+    
+    // testing event delegation
+    // mostly inline events
+    // and e.stopPropagation(), e.preventDefault()
+
+    casper
+    .start('./fixtures/events.html')
+    .thenClick('.normal', function () {
+        test.assertNotVisible('.outer')
+    })
+    .thenClick('.exp', function () {
+        test.assertNotVisible('.outer')
+        test.assertSelectorHasText('.msg', 'hello')
+        test.assertEval(function () {
+            return !window.location.hash
+        })
+    })
+    .thenClick('div', function () {
+        test.assertVisible('.outer')
+    })
+    .run(function () {
+        test.done()
+    })
+
+})