# 事件处理
# 监听事件
<div>
<button v-on:click="counter += 1">Add 1</button>
<p>Counter: {{ counter }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
counter: 0
}
})
</script>
# 事件处理方法
v-on:可以简写为@
<button @click="greet">Greet</button>
<script>
var vm = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
greet: function(event) {
alert('Hello');
if (event) {
alert(event.target.tagName)
}
}
}
})
</script>
# 内联方法传参
<button v-on:click="say('hi')">Say Hi</button>
<button v-on:click="say('No', $event)">Say No</button>
<script>
...
say: function(msg, event) {
alert(msg);
if (event) {
alert(event.target.innerHTML);
}
}
...
</script>
# 事件修饰符
在处理事件中调用 event.preventDefalt() 或 event.stopPropagation()式非常常见的。Vue提供了更好的方式来实现。方法只关系数据逻辑,而不区处理dom细节,事件修饰符:
- .stop 阻止事件继续传播
- .prevent 阻止事件默认行为
- .capture 捕获阶段触发事件
- .self event.target === self 仅自己点击,不能是子元素点击触发
- .once 事件只触发一次
- .passive 表示处理函数中不会调用event.preventDefault(),事件处理函数不会阻塞默认行为(比如滚动),可以理解为事件处理函数和默认行为异步执行。
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件只触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<div v-on:scroll.passive="onScroll">...</div>
v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
# 按键修饰符
监听键盘输入时,经常需要检查详细的按键,v-on在监听键盘事件时添加按键修饰符
- .enter
- .tab
- .delete (删除键和退格键)
- .esc
- .space
- .up
- .down
- .left
- .right 输入框监听事件顺序:keydown => keypress => textInput(event.data匹配值也可阻止默认输入内容) => keyup
<!-- 只有在点击的键key为 'Enter'时调用 vm.submit() -->
<input v-on:keyup.enter="submit">
<!-- 处理函数只会在 $event.key 等于 PageDown 时被调用 -->
<input v-on:keyup.page-down="onPageDown">
# 系统修饰键
- .ctrl
- .alt
- .shift
- .meta windows键或mac的command键
- .exact 准确的控制
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
# 鼠标按钮修饰符
限制修饰符处理函数仅使用特定的鼠标按钮
- .left
- .right
- .middle
<!-- mousedown => mouseup => click -->
<!-- 监听右键点击事件, JS原生根据event.button === 2来判断 -->
<div id="app">
<div @click.right="greet"
style="width:100px; height:100px; border: 1px solid #ccc;"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
greet: function(event) {
alert('Hello');
if (event) {
alert(event.target.tagName);
}
}
}
})
</script>
# 为什么在HTML中监听事件
这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:
- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 无须在 JavaScript 里手动绑定事件,ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。