Close
升级到 Vue 3 | Vue 2 EOL

事件处理

监听事件

我们可以使用 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
}
})

结果

上面的按钮被点击了 {{ counter }} 次。

方法事件处理程序

许多事件处理程序的逻辑会更复杂,因此将 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 提供了事件修饰符。回想一下,修饰符是指令的后缀,用点号表示。

<!-- 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>

使用修饰符时顺序很重要,因为相关代码按相同的顺序生成。因此,使用 v-on:click.prevent.self 将阻止所有点击,而 v-on:click.self.prevent 仅阻止对元素本身的点击。

2.1.4+ 中的新功能

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

与其他修饰符不同,其他修饰符仅适用于原生 DOM 事件,.once 修饰符也可以用于组件事件。如果你还没有阅读关于组件的内容,现在不用担心。

2.3.0+ 中的新功能

Vue 还提供了 .passive 修饰符,对应于addEventListenerpassive 选项

<!-- the scroll event's default behavior (scrolling) will happen -->
<!-- immediately, instead of waiting for `onScroll` to complete -->
<!-- in case it contains `event.preventDefault()` -->
<div v-on:scroll.passive="onScroll">...</div>

.passive 修饰符对于提高移动设备的性能特别有用。

不要将 .passive.prevent 放在一起使用,因为 .prevent 将被忽略,并且你的浏览器可能会显示警告。请记住,.passive 向浏览器传达你想阻止事件的默认行为。

键修饰符

在监听键盘事件时,我们经常需要检查特定的键。Vue 允许在监听键盘事件时为 v-on 添加键修饰符。

<!-- only call `vm.submit()` when the `key` is `Enter` -->
<input v-on:keyup.enter="submit">

你可以直接使用通过KeyboardEvent.key 公开的任何有效键名作为修饰符,方法是将它们转换为连字符分隔的格式。

<input v-on:keyup.page-down="onPageDown">

在上面的示例中,只有当 $event.key 等于 'PageDown' 时,才会调用处理程序。

键码

使用 keyCode 事件已弃用,并且可能在新的浏览器中不受支持。

使用 keyCode 属性也是允许的

<input v-on:keyup.13="submit">

Vue 在必要时为最常用的键码提供别名,以支持旧版浏览器。

一些键(.esc 和所有箭头键)在 IE9 中具有不一致的 key 值,因此如果你需要支持 IE9,应该优先使用这些内置别名。

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

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

系统修饰符键

2.1.0+ 中的新功能

你可以使用以下修饰符来仅在按下相应的修饰符键时触发鼠标或键盘事件监听器。

注意:在 Macintosh 键盘上,meta 是命令键 (⌘)。在 Windows 键盘上,meta 是 Windows 键 (⊞)。在 Sun Microsystems 键盘上,meta 被标记为实心菱形 (◆)。在某些键盘上,特别是 MIT 和 Lisp 机器键盘及其后继产品,例如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或“Meta”。

例如

<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>

请注意,修饰符键与普通键不同,当与 keyup 事件一起使用时,它们必须在事件发出时被按下。换句话说,keyup.ctrl 只有在你按住 ctrl 键的同时释放一个键时才会触发。如果你单独释放 ctrl 键,它不会触发。如果你确实想要这种行为,请改用 ctrlkeyCodekeyup.17

.exact 修饰符

2.5.0+ 中的新功能

.exact 修饰符允许控制触发事件所需的系统修饰符的精确组合。

<!-- this will fire even if Alt or Shift is also pressed -->
<button v-on:click.ctrl="onClick">A</button>

<!-- this will only fire when Ctrl and no other keys are pressed -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>

<!-- this will only fire when no system modifiers are pressed -->
<button v-on:click.exact="onClick">A</button>

鼠标按钮修饰符

2.2.0+ 中的新功能

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

为什么在 HTML 中使用监听器?

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

  1. 通过浏览 HTML 模板,更容易在你的 JS 代码中找到处理程序函数的实现。

  2. 由于你不需要在 JS 中手动附加事件监听器,因此你的 ViewModel 代码可以是纯粹的逻辑,并且与 DOM 无关。这使得测试变得更容易。

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