跳转到内容

事件处理

监听事件

我们可以使用 v-on 指令,我们通常将其简写为 @ 符号,来监听 DOM 事件并在它们被触发时运行一些 JavaScript。用法为 v-on:click="handler" 或使用快捷方式,@click="handler"

处理器值可以是以下之一

  1. 内联处理器:在事件被触发时执行的内联 JavaScript(类似于原生的 onclick 属性)。

  2. 方法处理器:指向组件上定义的方法的属性名或路径。

内联处理器

内联处理器通常用于简单情况,例如

js
const count = ref(0)
js
data() {
  return {
    count: 0
  }
}
template
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>

方法处理器

尽管许多事件处理器的逻辑会更复杂,可能无法使用内联处理器实现。这就是为什么 v-on 还可以接受您要调用的组件方法名称或路径。

例如

js
const name = ref('Vue.js')

function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` is the native DOM event
  if (event) {
    alert(event.target.tagName)
  }
}
js
data() {
  return {
    name: 'Vue.js'
  }
},
methods: {
  greet(event) {
    // `this` inside methods points to the current active instance
    alert(`Hello ${this.name}!`)
    // `event` is the native DOM event
    if (event) {
      alert(event.target.tagName)
    }
  }
}
template
<!-- `greet` is the name of the method defined above -->
<button @click="greet">Greet</button>

方法处理器自动接收触发它的原生 DOM 事件对象 - 在上面的示例中,我们能够通过 event.target 访问触发事件的元素。

另请参阅:[事件处理器的类型化](/guide/typescript/composition-api#typing-event-handlers)

另请参阅:[事件处理器的类型化](/guide/typescript/options-api#typing-event-handlers)

方法与内联检测

模板编译器通过检查 v-on 值字符串是否是有效的 JavaScript 标识符或属性访问路径来检测方法处理器。例如,foofoo.barfoo['bar'] 被视为方法处理器,而 foo()count++ 被视为内联处理器。

在内联处理器中调用方法

除了直接绑定到方法名之外,我们还可以在内联处理器中调用方法。这允许我们传递方法的自定义参数而不是原生事件

js
function say(message) {
  alert(message)
}
js
methods: {
  say(message) {
    alert(message)
  }
}
template
<button @click="say('hello')">Say hello</button>
<button @click="say('bye')">Say bye</button>

内联处理程序中访问事件参数

有时我们还需要在内联处理程序中访问原始DOM事件。您可以使用特殊变量 $event 将其传递到方法中,或者使用内联箭头函数。

template
<!-- using $event special variable -->
<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>

<!-- using inline arrow function -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
js
function warn(message, event) {
  // now we have access to the native event
  if (event) {
    event.preventDefault()
  }
  alert(message)
}
js
methods: {
  warn(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
  • .self
  • .capture
  • .once
  • .passive
template
<!-- the click event's propagation will be stopped -->
<a @click.stop="doThis"></a>

<!-- the submit event will no longer reload the page -->
<form @submit.prevent="onSubmit"></form>

<!-- modifiers can be chained -->
<a @click.stop.prevent="doThat"></a>

<!-- just the modifier -->
<form @submit.prevent></form>

<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div @click.self="doThat">...</div>

提示

使用修饰符时顺序很重要,因为相关代码是按相同顺序生成的。因此,使用 @click.prevent.self 将阻止元素及其子元素的 click 的默认行为,而 @click.self.prevent 只会阻止元素本身的点击默认行为。

.capture.once.passive 修饰符与原生 addEventListener 方法的选项相对应。

template
<!-- 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 @click.capture="doThis">...</div>

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

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

.passive 修饰符通常与触摸事件监听器一起使用,以在 提高移动设备的性能

提示

不要同时使用 .passive.prevent,因为 .passive 已经向浏览器表明您 想阻止事件的默认行为,如果您这样做,浏览器可能会显示警告。

键修饰符

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

template
<!-- only call `submit` when the `key` is `Enter` -->
<input @keyup.enter="submit" />

您可以直接使用通过 KeyboardEvent.key 提供的任何有效键名作为修饰符,只需将它们转换为短横线命名法即可。

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

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

键别名

Vue为最常用的键提供了别名

  • .enter
  • .tab
  • .delete(捕获“Delete”和“Backspace”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键

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

  • .ctrl
  • .alt
  • .shift
  • .meta

注意

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

例如

template
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

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

提示

请注意,修饰键与普通键不同,并且在使用keyup事件时,它们必须在事件发生时按下。换句话说,keyup.ctrl只有在您在按下ctrl键的同时释放一个键时才会触发。如果单独释放ctrl键,它不会触发。

.exact 修饰符

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

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

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

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

鼠标按钮修饰符

  • .left
  • .right
  • .middle

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

事件处理已加载