Vue3手册译稿 - 基础 - 事件处理

事件处理

事件监听

当DOM事件被触发时,我们使用v-on(缩写@符号)来监听事件,运行JavaScript。使用方法为v-on:click="method"或缩写为@click="method"
例如:

<div id="basic-event">
  <button @click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
Vue.createApp({
  data() {
    return {
      counter: 0
    }
  }
}).mount('#basic-event')

事件处理方法

因为有些事件处理比较复杂的逻辑,所以直接在v-on后面写JavaScript是不太现实的。所以v-on可以接受一个方法名来调用。例如:

<div id="event-with-method">
  <!-- `greet`就是在下面定义的方法名 -->
  <button @click="greet">Greet</button>
</div>
Vue.createApp({
  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)
      }
    }
  }
}).mount('#event-with-method')

事件方法传递参数

(感觉这个翻译靠谱点吧。原文是Methods in Inline Handlers)

<div id="inline-handler">
  <button @click="say('hi')">Say hi</button>
  <button @click="say('what')">Say what</button>
</div>
Vue.createApp({
  methods: {
    say(message) {
      alert(message)
    }
  }
}).mount('#inline-handler')

有时候我们需要在方法中访问DOM的原生事件句柄,你可以通过$event传递进来:

<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
// ...
methods: {
  warn(message, event) {
    // now we have access to the native event
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

多事件处理

你可以在一个事件中调用多个用逗号分隔的方法,如下:

<!-- 按钮点击时one() 和 two() 都会执行 -->
<button @click="one($event), two($event)">
  Submit
</button>
// ...
methods: {
  one(event) {
    // 第一个事件的业务逻辑
  },
  two(event) {
    // 第二个事件的业务逻辑
  }
}

事件修饰符

事件响应过程中经常会用到event.preventDefault()event.stopPropagation()。虽然我们可以在方法里简单的调用,但最好方法完全是数据逻辑而不必去处理DOM细节。
针对这个问题,Vue提供了v-on的修饰符。调用方法是在指令后面加一个后缀。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止冒泡事件 -->
<a @click.stop="doThis"></a>

<!-- 表单提交不会刷新页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰符可以嵌套 -->
<a @click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form @submit.prevent></form>

<!-- 事件监听使用捕获模式 -->
<!-- i.e. 穿透执行,从下向上冒呗 -->
<div @click.capture="doThis">...</div>

<!--只有事件的目标是自己才触发 -->
<!-- i.e. 不是从子元素触发的 -->
<div @click.self="doThat">...</div>

[info]提示
使用修饰符顺序问题同代码的书写顺序。因此使用@click.prevent.self会阻止所有点击而@click.sel.prevent只会阻止元素自身的点击。

<!-- 最多只触发一次 -->
<a @click.once="doThis"></a>

.once不像其他修饰符只能用于原生组件,它也可以应用于组件。如果你还没有阅读过组件知识,先别烦神了。
Vue同时提供.passive修饰符,同addEventListenerpassive选项一样。

<!-- 滚动事件默认是触发的 -->
<!-- 替代 `onScroll` 完成-->
<!--内含 `event.preventDefault()`  -->
<div @scroll.passive="onScroll">...</div>

passive修饰符对移动端性能提升尤为有用。

[info]不要把.passive.prevent同时使用,因为prevent会被忽略且浏览器会收到警告信息。记住,.passive通知浏览器你不想阻止事件的默认行为。

键修饰符

我们经常需要监听键盘上特殊按键行为。Vue允许使用v-on@来监听键盘的输入:

<!-- 当按下回车后会调用 `vm.submit()` -->
<input @keyup.enter="submit" />

你可以使用任意通过`keyboardEvent.key暴露出来的键名作为修饰符,只要使用驼峰命名即可。

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

PageDown按钮触发事件。

键别名

Vue提供了大部分常用键的别名

  • .enter
  • .tab
  • .delete(同时捕获 "Delete" 和 "Backspace" 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统控制键修饰符

当相应的修饰键被按下时,你可以使用以下修饰键触发鼠标或键盘事件监听:

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

[info]mac电脑meta指的是命令键(⌘),Windows电脑指的是windows键(⊞)。在sun公司的微系统键盘,meta指的是实心菱形键(◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在符号键盘上,meta 被标记为“META”或者“Meta”。

示例:

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

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

[warning] 系统控制键修饰在使用key.up时不同于普通键,它在按下时指令就发出了。换句话说,只有按下ctrl释放其它键时才会触发事件,单单释放ctrl键并不会触发事件。

.exact修饰符

exact修饰符控制系统组合键触发事件:

<!-- Alt或Shift键同时按下时也会执行-->
<button @click.ctrl="onClick">A</button>

<!-- 没有其他键被按下时才会执行 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!--没有系统控制键被按下时才会执行 -->
<button @click.exact="onClick">A</button>

鼠标修饰符

  • .left
  • .right
  • .middle
    鼠标按钮修饰符会阻事件只响应鼠标特定按钮点击。

为什么在HTML中监听?

你可能注意到了所有一的事件监听貌似违反了“关键点隔离”这个好的旧规则。请放宽心,因为所有Vue的操作函数及表达式均已绑定到当前视图的ViewModel,维护起来一点也不困难。事实上使用v-on@还有一些优点。

  1. 通过浏览HTML模板很容易定位到操作函数的JS实现代码。
  2. 因为你不需要再在JS代码里人工设置监听,你的ViewModel代码只需要关注纯逻辑和DOM。这也更容易进行测试。
  3. 当一个ViewModel被销毁,所有的事件监听也会移除。不需要再手工清除。

posted on 2021-03-07 21:55  zhouyu  阅读(131)  评论(0编辑  收藏  举报

导航