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被销毁时,所有的事件监听器都会被自动删除。你不必担心它的自我清理。