事件处理
监听事件
可以用 v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
实例:
<div id="box">
<button v-on:click="counter++">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
el: '#box',
data: {
counter: 0
}
})
事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on
指令中是不可行的。因此 v-on
还可以接收一个需要调用的方法名称。
实例:
<div id='box'>
<button @click='fn'>
click
</button>
</div>
let vm = new Vue({
el:'#box',
data:{
name:'retr0'
}
method:{
//当@click='fn'不加括号时,可以直接使用形参eve
//eve是原生 DOM 事件
//当@click='fn($event)'加括号时,需要传入实参$event
fn(eve){
alert(`hello ${this.name}`);
if(eve){
alert(eve.target.tagName);
}
}
}
})
内联处理器中的方法
除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// ...
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
.self
.once
.passive
.stop
<!-- 阻止事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 阻止事件冒泡,没有表达式 -->
<a v-on:click.stop></a>
.prevent
<!-- 阻止浏览器默认行为 -->
<div :click.prevent='fn()'></div>
<!-- 阻止默认行为,没有表达式 -->
<div :click.prevent></div>
.self
<!-- 只当事件是从侦听器绑定的元素本身触发时才触发回调 -->
<ul @click.self='fn2()'>
<li v-for='data in datalist' @click='fn()'>{{data}}</li>
</ul>
.once
<!-- 只触发一次回调 -->
<div @click.once='fn'></div>
如何不用once做到解绑事件:
<!-- 通过状态isActive进行短路 -->
<!-- 需要注意,这里的函数表达式必须加() -->
<div @click='isActive && fn()'>解绑测试</div>
.passive
每次事件产生,浏览器都会去查询一下是否有preventDefault
阻止该次事件的默认动作。我们加上passive就是为了告诉浏览器,不用查询了,我们没用 preventDefault阻止默认动作。这里一般用在滚动监听,@scroll,@touchmove 。因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。我们通过passive将内核线程查询跳过,可以大大提升滑动的流畅度
<!-- 以 { passive: true } 模式添加侦听器 -->
<div @click.passive='fn'></div>
按键修饰符
<!-- 只有在按下回车键的时才会触发该事件 -->
<input @keyup.enter='fn()'>
<!-- 支持连缀 -->
<input @keyup.enter.ctrl='fn()'>
<!-- 支持keyCode -->
<input @keyup.13='fn()'>
其实通过以下方法完成的:
<div id='box'>
<input @keyup='fn1($event)'>
</div>
new Vue({
el:'#box',
methods:{
fn1(eve){
if(eve.keyCode == 13){
......
}
}
}
})