VueJS 事件处理
-
为什么在 HTML 中监听事件
你可能注意到这种事件监听的方式违背了关注点分离(separation of concern)传统理念。不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。
-
如何监听 DOM 事件
我们可以使用 v-on 指令来监听 DOM 事件并在触发事件时运行一些JavaScript。
尝试一下<div id="example-1"> <button v-on:click="counter += 1">增加 1</button> <p>这个按钮被点击了 {{ counter }} 次。</p> </div> <script> var example1 = new Vue({ el: '#example-1', data: { counter: 0 } }); </script>
不过,许多事件处理程序的逻辑会更加复杂,因此将 JavaScript 保持在 v-on 属性的值中是不可行的。 这就是为什么 v-on 还可以接受您要调用的方法名称的原因。
尝试一下<div id="example-2"> //“greet” 是下面定义的方法的名称 <button v-on:click="greet">greet</button> </div> <script> var example2 = new Vue({ el: '#example-2', data: { name: 'Vue.js' }, // 在“方法”对象下定义方法 methods: { greet: function (event) { // `this` 内部方法指向Vue实例 alert('Hello ' + this.name + '!') // `event` 是本DOM事件 if (event) { alert(event.target.tagName) } } } }); </script>
除了直接绑定到方法名称之外,我们还可以在嵌入式 JavaScript 语句中使用方法:
尝试一下<div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div> <script> new Vue({ el: '#example-3', methods: { say: function (message) { alert(message) } } }); </script>
有时我们还需要在内联语句处理程序中访问原始 DOM 事件。 您可以使用特殊的 $event 变量将其传递给方法://HTML <button v-on:click="warn('表格尚未提交。', $event)">Submit</button> //JS methods: { warn: function (message, event) { // 现在我们可以访问本机事件 if (event) { event.preventDefault() } alert(message) } }
-
如何监听 DOM 事件
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。 尽管我们可以轻松地在方法内部执行此操作,但最好是这些方法可以纯粹与数据逻辑有关,而不是必须处理 DOM 事件详细信息。为了解决此问题,Vue 为 v-on 提供了事件修饰符。 回想一下修饰符是用点表示的指令后缀。- .stop
- .prevent
- .capture
- .self
- .once
- .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> // 只当事件在该元素本身(而不是子元素)触发时触发回调 <div v-on:click.self="doThat">...</div>
使用修饰符时顺序很重要,因为相关代码以相同顺序生成。 因此,使用 v-on:click.prevent.self 将阻止所有单击,而 v-on:click.self.prevent 将仅防止单击元素本身。
.once 与其他修饰符(本机DOM事件专用)不同,.once 修饰符还可以用于组件事件。// click 事件只能点击一次,2.1.4版本新增 <div v-on:click.once="doThis">...</div>
Vue 还提供了 .passive 修饰符,与 addEventListener 的被动选项相对应。.passive 修饰符对于提高移动设备的性能特别有用。// 滚动事件的默认行为(滚动)将发生 // 立即,而不是等待onScroll完成 // 如果它包含`event.preventDefault()` <div v-on:scroll.passive="onScroll">...</div>
请勿同时使用 .passive 和 .prevent,因为 .prevent 将被忽略,并且您的浏览器可能会向您显示警告。 请记住,.passive 会与您的浏览器进行通信,您不想阻止该事件的默认行为。
-
按键修饰符
当需要旧版浏览器支持时,Vue 为最常用的键代码提供别名:- .enter
- .tab
- .delete (捕获 "删除" 和 "退格" 键)
- .esc
- .space
- .up
- .down
- .ctrl (2.1.0+版本新增)
- .alt (2.1.0+版本新增)
- .shift (2.1.0+版本新增)
- .meta (2.1.0+版本新增)
- .left (2.2.0+版本新增)
- .right (2.2.0+版本新增)
- .middle (2.2.0+版本新增)
- .exact (2.5.0+版本新增)
示例:// Alt + C <input @keyup.alt.67="clear"> // Ctrl + Click <div @click.ctrl="doSomething">Do something</div> // 即使同时按下Alt或Shift也会触发 <button @click.ctrl="onClick">A</button> //仅在按Ctrl键且未按下其他任何键时才会触发 <button @click.ctrl.exact="onCtrlClick">A</button> //仅当未按下系统修改器时才会触发 <button @click.exact="onClick">A</button>