温故知新 Vue 3: Lesson 6

142 阅读3分钟

温故知新 Vue 3: Lesson 6

Event Handling

listen to DOM events and run some JavaScript when they're triggered.

The usage would be v-on:click="methodName" or with the shortcut, @click="methodName"

监听 DOM 事件, 并且在事件触发时运行特定的 js 代码.

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

Method Event Handlers

v-on can also accept the name of a method you'd like to call.

v-on 也可以接受 method name, 相当于 callback. 参数是 DOM event.

<div id="event-with-method">
  <!-- `greet` is the name of a method defined below -->
  <button @click="greet">Greet</button>
</div>
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)
    }
  }
}

Methods in Inline Handlers

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

Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special $event variable.

v-on 的 inline handler 如果需要访问原生的 DOM 事件, 可以通过$event. 如果是 child component emit 的 custome event. $event 表示 custom 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)
  }
}

Multiple Event Handlers

<!-- both one() and two() will execute on button click -->
<button @click="one($event), two($event)">Submit</button>
methods: {
  one(event) {
    // first handler logic...
  },
  two(event) {
    // second handler logic...
  }
}

Event Modifiers

Vue provides event modifiers for v-on to deal with DOM event details.

vue 提供了 event modifier 来处理 DOM 事件的细节

.stop
.prevent
.capture
.self
.once
.passive
<!-- 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>

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

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

Order matters when using modifiers because the relevant code is generated in the same order.

modifier 的顺序会影响实际的结果.

Therefore using @click.prevent.self will prevent all clicks while @click.self.prevent will only prevent clicks on the element itself.

@click.prevent.self 先 prevent, 所以会拦截所有的 click. @click.self.prevent先 self, 因此只会拦截他合格元素上的 click.

Key Modifiers

When listening for keyboard events, we often need to check for specific keys.

有些时候你需要监听特定的键.

You can directly use any valid key names exposed via KeyboardEvent.keyas modifiers by converting them to kebab-case.

你可以使用 KeyboardEvent.key 里面包含的键, 使用时转化成 kebab-case

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

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

Key Aliases

.enter
.tab
.delete (captures both "Delete" and "Backspace" keys)
.esc
.space
.up
.down
.left
.right

System Modifier Keys

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

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

.exact Modifier

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

Mouse Button Modifiers

.left
.right
.middle

Why Listeners in HTML?

all Vue handler functions and expressions are strictly bound to the ViewModel that's handling the current view, it won't cause any maintenance difficulty.

所有的 vue handler 都是与处理当前 View 的 ViewModel 进行严格绑定.

In fact, there are several benefits in using v-on or @:

  1. It's easier to locate the handler function implementations within your JS code by skimming the HTML template. 随便瞟一眼 HTML, 容易定位到对应的函数

  2. Since you don't have to manually attach event listeners in JS, your ViewModel code can be pure logic and DOM-free. This makes it easier to test. 你不用手动绑定 event listener, 你的 ViewModel 只需要关注逻辑, 不需要直接操作 DOM.

  3. When a ViewModel is destroyed, all event listeners are automatically removed. You don't need to worry about cleaning it up yourself. ViewModel destroy 后, 所有的 event listener 都会自动移除.

本文使用 mdnice 排版