9. Event Handling(事件处理)

事件处理

听取事件

我们可以使用v-on指令来侦听DOM事件并在触发时运行一些JavaScript。

例如:

<div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div>

var example1 = new Vue{ el: '#example-1', data: { counter: 0 } })

结果:

方法事件处理程序

许多事件处理程序的逻辑将会更复杂,因此将JavaScript保存在v-on属性的值中并不可行。这就是为什么v-on也可以接受你想要调用的方法的名称。

例如:

<div id="example-2"> <!-- `greet` is the name of a method defined below --> <button v-on:click="greet">Greet</button> </div>

var example2 = new Vue{ el: '#example-2', data: { name: 'Vue.js' }, // define methods under the `methods` object methods: { greet: function (event) { // `this` inside methods points to the Vue instance alert('Hello ' + this.name + '!') // `event` is the native DOM event if (event) { alert(event.target.tagName) } } } }) // you can invoke methods in JavaScript too example2.greet() // => 'Hello Vue.js!'

结果:

内联处理程序中的方法

除了直接绑定到方法名称外,我们还可以在内联JavaScript语句中使用方法:

<div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div>

new Vue{ el: '#example-3', methods: { say: function (message) { alert(message) } } })

结果:

有时我们还需要访问内联语句处理程序中的原始DOM事件。您可以使用特殊$event变量将它传递给一个方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)"> Submit </button>

// ... methods: { warn: function (message, event) { // now we have access to the native event if (event) event.preventDefault() alert(message) } }

事件修饰符

在事件处理程序中调用event.preventDefault()event.stopPropagation()内部是非常普遍的需要。尽管我们可以在方法内部轻松完成此操作,但如果方法纯粹是关于数据逻辑而不是处理DOM事件细节,那将会更好。

为了解决这个问题,Vue提供事件修饰符v-on。回想一下,修饰符是用点表示的指令后缀。

  • .stop

  • .prevent

  • .capture

  • .self

  • .once

<!-- the click event's propagation will be stopped --> <a v-on:click.stop="doThis"></a> <!-- the submit event will no longer reload the page --> <form v-on:submit.prevent="onSubmit"></form> <!-- modifiers can be chained --> <a v-on:click.stop.prevent="doThat"></a> <!-- just the modifier --> <form v-on:submit.prevent></form> <!-- use capture mode when adding the event listener --> <!-- i.e. an event targeting an inner element is handled here before being handled by that element --> <div v-on:click.capture="doThis">...</div> <!-- only trigger handler if event.target is the element itself --> <!-- i.e. not from a child element --> <div v-on:click.self="doThat">...</div>

使用修饰符时的顺序很重要,因为相关的代码是以相同的顺序生成的。因此,使用@click.prevent.self会阻止所有的点击,@click.self.prevent只会阻止点击元素本身。

New in 2.1.4+

<!-- the click event will be triggered at most once --> <a v-on:click.once="doThis"></a>

与其他修饰符不同,它们是本地DOM事件专有的,.once修饰符也可用于组件事件。如果你还没有阅读组件,现在不要担心。

关键修饰符

在监听键盘事件时,我们经常需要检查常见的键码。Vue还允许v-on在侦听关键事件时添加关键修饰符:

<!-- only call vm.submit() when the keyCode is 13 --> <input v-on:keyup.13="submit">

记住所有keyCodes是一件麻烦的事情,所以Vue为最常用的键提供了别名:

<!-- same as above --> <input v-on:keyup.enter="submit"> <!-- also works for shorthand --> <input @keyup.enter="submit">

以下是关键修饰符别名的完整列表:

  • .enter

  • .tab

  • .delete (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

您还可以通过全局config.keyCodes对象定义自定义键修饰符别名:

// enable v-on:keyup.f1 Vue.config.keyCodes.f1 = 112

自动键修饰符

New in 2.5.0+

您也可以直接使用KeyboardEvent.key作为修饰符公开的任何有效密钥名称,方法是将它们转换为kebab-case:

<input @keyup.page-down="onPageDown">

在上面的例子中,处理程序只会在$event.key === 'PageDown'时被调用。

一些键(.esc和所有箭头键)key在IE9中的值不一致,如果您需要支持IE9,则应该首选它们的内置别名。

系统修饰键

New in 2.1.0+

只有在按下相应的修饰键时,才可以使用以下修饰符来触发鼠标或键盘事件侦听器:

  • .ctrl

  • .alt

  • .shift

  • .meta

注意:在Macintosh键盘上,meta是命令键(⌘)。在Windows键盘上,meta是Windows键(⊞)。在Sun Microsystems键盘上,meta标记为实心菱形(◆)。在特定的键盘上,特别是MIT和Lisp机器的键盘和后继机器,如Knight键盘,Space-Cadet键盘,meta被标记为“META”。在符号键盘上,元标记为“META”或“Meta”。

例如:

<!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div>

请注意,修饰键与常规键不同,当与keyup事件一起使用时,必须在事件发出时按下它们。换句话说,keyup.ctrl只有在您按住时松开按键才会触发ctrl。如果您ctrl单独释放密钥,它将不会触发。

.exact 修饰符

New in 2.5.0+

.exact修改应与其他系统调节剂联合使用,以表明改性剂的精确组合必须按下处理程序。

<!-- this will fire even if Alt or Shift is also pressed --> <button @click.ctrl="onClick">A</button> <!-- this will only fire when only Ctrl is pressed --> <button @click.ctrl.exact="onCtrlClick">A</button>

鼠标按钮修饰符

New in 2.2.0+

  • .left

  • .right

  • .middle

这些修饰符将处理程序限制为由特定鼠标按钮触发的事件。

为什么HTML中有监听者?

您可能担心整个事件监听方法违反了有关“关注点分离”的旧规则。请放心 - 因为所有Vue处理函数和表达式都严格绑定到处理当前视图的ViewModel上,所以不会导致任何维护困难。事实上,使用中有几个好处v-on

1. 通过浏览HTML模板,可以更轻松地在JS代码中查找处理函数实现。

2. 由于您不必手动在JS中附加事件侦听器,因此您的ViewModel代码可以是纯逻辑和无DOM的。这也使测试更容易。

3. 当ViewModel被销毁时,所有的事件监听器都会被自动删除。你不必担心它的自我清理。