ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[[官方文档]](https://vuejs.org/v2/guide/events.html) `v-on:eventName=""` We can use the`v-on`directive to listen to DOM events and run some JavaScript when they’re triggered. ---- 目录: [TOC] ---- ## Explicit Events ### Listening to Events ~~~html <div id="example-1"> <button v-on:click="counter += 1">Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div> ~~~ ~~~javascript var example1 = new Vue({ el: '#example-1', data: { counter: 0 } }) ~~~ ### Method Event Handlers ~~~html <div id="example-2"> <!-- `greet` is the name of a method defined below --> <button v-on:click="greet">Greet</button> </div> ~~~ ~~~javascript 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!' ~~~ ### Methods in Inline Handlers ~~~html <div id="example-3"> <button v-on:click="say('hi')">Say hi</button> <button v-on:click="say('what')">Say what</button> </div> ~~~ ~~~javascript new Vue({ el: '#example-3', methods: { say: function (message) { alert(message) } } }) ~~~ ## Listeners in HTML The whole `Vue` event listening approach violates the good old rules about “separation of concerns”. 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. In fact, there are several benefits in using`v-on`: 1. It’s easier to locate the handler function implementations within your JS code by skimming the HTML template. 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. 3. When a ViewModel is destroyed, all event listeners are automatically removed. You don’t need to worry about cleaning it up yourself. ## Event Modifiers It is a very common need to call `event.preventDefault()` or `event.stopPropagation()` inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details. To address this problem, Vue provides **event modifiers** for `v-on`. Recall that modifiers are directive postfixes denoted by a dot. * `.stop` * `.prevent` * `.capture` * `.self` * `.once` * `.passive` ~~~html <!-- 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> <!-- the click event will be triggered at most once --> <a v-on: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 v-on:scroll.passive="onScroll">...</div> ~~~ >[warning] Order matters when using modifiers because the relevant code is generated in the same order. Therefore using `v-on:click.prevent.self` will prevent **all clicks** while `v-on:click.self.prevent` will only prevent clicks on the element itself. >[warning] Unlike the other modifiers, which are exclusive to native DOM events, the `.once` modifier can also be used on [component events](https://vuejs.org/v2/guide/components-custom-events.html). The`.passive`modifier, corresponding to [`addEventListener`‘s`passive`option](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters), is especially useful for improving performance on mobile devices. >[warning] Don’t use `.passive` and `.prevent` together. Because `.prevent` will be ignored and your browser will probably show you a warning. Remember, `.passive` communicates to the browser that you *don’t* want to prevent the event’s default behavior. ## Key Modifiers When listening for keyboard events, we often need to check for specific keys. Vue allows adding key modifiers for`v-on`when listening for key events: ~~~html <!-- only call `vm.submit()` when the `key` is `Enter` --> <input v-on:keyup.enter="submit"> ~~~ You can directly use any valid key names exposed via [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)as modifiers by converting them to kebab-case. ~~~html <input v-on:keyup.page-down="onPageDown"> ~~~ In the above example, the handler will only be called if`$event.key`is equal to`'PageDown'`. ### System Modifier Keys You can use the following modifiers to trigger mouse or keyboard event listeners only when the corresponding modifier key is pressed: * `.ctrl` * `.alt` * `.shift` * `.meta` >[info] Note: > On Macintosh keyboards, **meta** is the command key (⌘). > On Windows keyboards, **meta** is the Windows key (⊞). > On Sun Microsystems keyboards, **meta** is marked as a solid diamond (◆). > On certain keyboards, specifically MIT and Lisp machine keyboards and successors, such as the Knight keyboard, space-cadet keyboard, **meta** is labeled “META”. > On Symbolics keyboards, **meta** is labeled “META” or “Meta”. For example: ~~~html <!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div> ~~~ >[warning] Note that modifier keys are different from regular keys and when used with`keyup`events, they have to be pressed when the event is emitted. > In other words,`keyup.ctrl`will only trigger if you release a key while holding down`ctrl`. It won’t trigger if you release the`ctrl`key alone. If you do want such behaviour, use the`keyCode`for`ctrl`instead:`keyup.17`. ### `.exact`Modifier The `.exact` modifier allows control of the exact combination of system modifiers needed to trigger an event. ~~~html <!-- 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` These modifiers restrict the handler to events triggered by a specific mouse button. ## Tips ### eventBus--事件总线 [[Vue的this.$root.Bus.$on事件被多次触发、多次监听的问题]](https://blog.csdn.net/qq_26963495/article/details/86489063) 前端vue项目中,各个组件(非父子关系也可)之间可以通过Bus进行事件通信。 main.js中: ~~~Javascript import Vue from 'vue' const Bus = new Vue(); const app = new Vue({ el: '#app', data: {Bus}, router, components: {App}, template: '<App/>' }) ~~~ 进过如上配置后即可在各个组件中通过如下: ~~~Javascript this.$root.Bus.$emit("事件名", 参数1, 参数2, ...) ~~~ 来给总线Bus发一条事件信息。 其他组件通过如下: ~~~Javascript this.$root.Bus.$on("事件名", 回调函数) ~~~ 来监听总线Bus中的某个事件,执行回调函数了。 问题描述: 有时候会发生事件只被`emit`触发了一次,但是回调函数却被执行了多次的现象。这种现象往往发生在页面跳转退出后重新进入的时候。 产生原因: `this.$root.Bus.$on`实际是向Bus容器中添加一个事件监听器,当页面跳转时,原来的vue组件被注销,但是原来vue组件向Bus容器中添加的事件监听器并不会被移除。因此,当下次进入这个vue组件对应的页面时,执行到`this.$root.Bus.$on`时,又会向Bus容器中添加一个重复的事件监听器,以此类推,导致Bus容器中有很多个一模一样的事件监听器,从而导致事件只被触发一次,但是回调函数被执行多次的现象。 解决方案: 在vue组件的`beforeDetory`钩子函数中将本vue组件往Bus容器中添加的时间监听器全部手动移除。 ~~~Javascript //在vue对象的methods域中定义一个函数,专门移除事件监听器 offxxxListener: function () { this.$root.Bus.off("事件名"); this.$root.Bus.off("事件名"); this.$root.Bus.off("事件名"); }, //在vue对象的beforeDestroy钩子中调用以上函数 beforeDestroy() { this.offxxxListener(); }, ~~~ ### $event的理解 [[CSDN-$event的理解]](https://blog.csdn.net/dangbai01_/article/details/83864498)