事件处理

大概这是个坑吧......

绑定语法。

    <!-- 复习一下缩写,v-on是@,v-bind是: -->
    <div id="vm1">
        <button @click="counter += 1">Add 1</button>
        <p>The button above has been clicked {{ counter }} times.</p>
    </div>

    <script type="text/javascript">
        var vm1 = new Vue({
            el: '#vm1',
            data: {
                counter: 0
            }
        })
    </script>

这里复习一下v-on的缩写,相信我,写的多了,你就会觉得少打两个字母是幸福。
结果自然是这样的。


点击的次数被忠实的记录下来,除非你刷新

当然,如果这里我要把点击次数上传或者做一些其他的修改,耦合程度就有点不太让人能接受了,于是可以这么写嘛。

    <!-- 为了让事件和HTML解耦,定义一个方法 -->
    <div id="vm2">
        <button v-on:click="greet">Greet</button>
    </div>

    <script type="text/javascript">
        var vm2 = new Vue({
            el: '#vm2',
            data: {
                name: 'Vue.js'
            },
            methods: {
                greet: function(event){

                    //this在当前上下文中指向Vue实例
                    alert('Hello ' + this.name + '!');

                    //event是原生dom事件
                    if(event){
                        alert(event.target.tagName);
                    }

                    console.log(event);
                }
            }
        })
    </script>

当然,在事件中,任何function里的this指针都指向本Vue实例。
结果如下。


点击后触发

在前面,我们已经无数次应用过这些了(所以文档是用来查的)
哦,漏了个小兄弟


在这里

代码的意思是,如果event是原生事件对象,就alert输出触发它的元素名称。
所以也间接求证了,Vue绑定的尽量是原生事件对象。

在v-on:绑定中调用事件也是可以的。

    <!-- 内联处理器中的方法 -->
    <div id="vm3">
        <button v-on:click="say('hi')">Say hi</button>
        <button v-on:click="say('what')">Say what</button>
    </div>

    <script type="text/javascript">
        var vm3 = new Vue({
            el: '#vm3',
            methods: {
                say: function(message){
                    alert(message);
                }
            }
        })
    </script>

根据传入的参数,会alert不同的内容。


hi

what

这种方法类似于在dom的onxx事件中书写JavaScript代码和调用函数,仁者见仁吧。

联系例子二和刚才的例子,如果我们要在内联语句处理器中访问原生的dom事件对象,怎么做呢?
Vue提供了封装的对象。

    <!-- 如果需要在内联语句处理器中访问原生DOM的事件对象,可以将它以$event传入方法中  -->
    <div id="vm4">
        <button v-on:click="warn('Form cannot be submitted yet.', $event)">
            Submit
        </button>
    </div>

    <script type="text/javascript">
        var vm4 = new Vue({
            el: '#vm4',
            methods: {
                warn: function(message, event){
                    if(event){
                        event.preventDefault()
                    }

                    alert(message)
                }
            }
        })
    </script>

可以在内联语句处理中,传入$event对象。


提交结果

为什么表单无法提交呢?因为我们调用了阻止对象默认事件的方法(event.preventDefault()),该方法最常用的场景就是用来阻止<a>标签的href跳转和<form>标签的submit提交。当然,它也是原生dom中的API。
还有一个和它使用频率相同的API,即阻止事件冒泡(event.stopPropagantion())的API,事件冒泡,是当该元素接收到事件之后,会向上传导,直到传导到最高级的父元素(<html>标记)为止。俗称的“牵一发而动全身”,就是这个道理。举个例子,假如说,你在页面中的<html>标记上,写了一个click事件,那么无论底下哪个元素被点击了,都会触发<html>标记的click
事件。。。。。。
这么一想的话,这两个还挺重要的,不过老这么写,也挺难过。。。

事件修饰符

常见的六个

  • .stop 阻止事件冒泡 stopPropagation()
  • .prevent 阻止元素默认行为 preventDefault()
  • .capture 即内部元素的事件先在此处理,然后再交给内部元素处理(逆stopPropagation())
  • .self 只处理自身触发的事件
  • .once v2.1.4新增 事件只触发一次
  • .passive v2.3.0新增 对应addEventListener()中的 passive 选项
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>


<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

几点提示:

  • 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

  • .once除了可以对原生的DOM事件修饰之外,还可以用于自定义的组件事件中。其他的修饰符不能做到这一点。

  • .passive修饰符应用得当对移动端性能提升比较明显

  • 不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

按键修饰符

可以将对应的事件与按键相关联。

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

也可以直接将KeyboardEvent.key暴露的任意有效按键名按照kebab-case的写法来作为修饰符。

<!-- 只有在 `key` 是 `PageDown` 时调用 -->
<input v-on:keyup.page-down="onPageDown">

实际上,使用 v-on 有几个好处:

扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。

因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。

当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容