文章目录
1. 监听事件
可以用 v-on 指令监听 DOM 事件
,并在触发时运行一些 JavaScript 代码。
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
2.事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在v-on
指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称。
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是当前事件对象的DOM
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接调用方法
example2.greet() // => 'Hello Vue.js!'
3. 内联处理器的方法
除了直接绑定到一个方法,也可以在内联 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 把它传入方法:
<div id="example-4">
//<a href="www.baidu.com" @click="warn('点击了一下',$event)">点击跳转百度</a>两种写法都可以
<a href="https://www.baidu.com" @click="warn('点击了一下',event)">点击跳转百度</a>
</div>
new Vue({
el:"#example-4",
methods:{
warn:function(msg,event){
if(event){
//取消事件的默认动作。
event.preventDefault();
}
alert(msg)
}
}
})
4. 事件修饰符
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
- .
.self
.once
.passive
4.1 .stop
//HTML
<div id="app-7">
<div @click="outEvent" style="background: deeppink; height: 200px;">
<div @click.self="middleEvent" style="background: hotpink; height: 100px;">
<div @click="innerEvent" style="background: lightpink; height: 50px;">
//.stop在这里
<button @click.stop="buttonEvent">点击</button>
<br />
inner
</div>
middle
</div>
out
</div>
</div>
//JS
new Vue({
el:"#app-7",
methods:{
outEvent:function(){
console.log("触发了外层div事件")
},
middleEvent:function(){
console.log("触发了中层div事件")
},
innerEvent:function(){
console.log("触发了内层div事件")
},
buttonEvent:function(){
console.log("触发了按钮事件")
}
}
})
button
上使用了.stop修饰符
阻止冒泡只触发按钮事件按钮上层的事件都被阻止
4.2 .prevent
.prevent
和前面的例子preventDefault()
作用一样
4.3.capture
//HTML
<div id="app-7">
<div @click="outEvent" style="background: deeppink; height: 200px;">
//.capture在这里
<div @click.capture="middleEvent" style="background: hotpink; height: 100px;">
<div @click="innerEvent" style="background: lightpink; height: 50px;">
<button @click="buttonEvent">点击</button>
<br />
inner
</div>
middle
</div>
out
</div>
</div>
//JS
new Vue({
el:"#app-7",
methods:{
outEvent:function(){
console.log("触发了外层div事件")
},
middleEvent:function(){
console.log("触发了中层div事件")
},
innerEvent:function(){
console.log("触发了内层div事件")
},
buttonEvent:function(){
console.log("触发了按钮事件")
}
}
})
先看看没有加.capture
前的运行结果
可以看出事件的触发顺序是从里到外
再看看加了.capture
运行之后的结果
- 由此可以得出加了
.capture
之后事件的触发顺序先触发有.capture的事件再从里到外的顺序触发
4.4 .self
<div id="app-7">
<div @click="outEvent" style="background: deeppink; height: 200px;">
//.self在这里
<div @click.self="middleEvent" style="background: hotpink; height: 100px;">
<div @click="innerEvent" style="background: lightpink; height: 50px;">
<button @click="buttonEvent">点击</button>
<br />
inner
</div>
middle
</div>
out
</div>
</div>
new Vue({
el:"#app-7",
methods:{
outEvent:function(){
console.log("触发了外层div事件")
},
middleEvent:function(){
console.log("触发了中层div事件")
},
innerEvent:function(){
console.log("触发了内层div事件")
},
buttonEvent:function(){
console.log("触发了按钮事件")
}
}
})
.self
修饰的分两种情况。第一种情况不点.self修饰的事件则该事件不触发:
第二种情况,你去点击.self修饰的事件则该事件会触发
4.5 .once
注:.once是2.1.4新增的
.once
修饰的事件只触发一次:
<div id="app-5">
<a href="https://www.baidu.com" @click.once="jump">点击跳转百度</a>
//.once还可以在其他修饰符后面,没有先后顺序
<a href="https://www.baidu.com" @click.prevent.once="jump">点击跳转百度</a>
</div>
new Vue({
el:"#app-5",
methods:{
jump:function(){
console.log("触发了跳转")
}
}
})
4.6 .passive
注:.passive在2.3.0被加入
浏览器每次都会去查询一下是否有preventDefault
阻止该次事件的默认动作。我们加上.passive
就是为了告诉浏览器不用查询了我们没用preventDefault阻止默认动作。
5. 按键修饰符
<div id="app-9">
<[email protected]和@keyup.13效果一样,键盘按下Enter键触发-->
<input @keyup.enter="enter" />
<input @keyup.13="enter" />
</div>
new Vue({
el:"#app-9",
methods:{
enter:function(){
alert("敲击了一下Enter键")
}
}
})
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
你还可以通过全局config.keyCodes
对象自定义按键修饰符别名:
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
请注意修饰键与常规按键不同,在和 keyup 事件一起用时
,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键
,才能触发 keyup.ctrl+c。
而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。
<!-- Ctrl + C 按住Ctrl不释放,释放C触发-->
<input @keyup.ctrl.67="doSomething" />
<!-- Ctrl + C 按住Ctrl不释放,释放C触发-->
<!-- Ctrl + C 按住C不释放,释放Ctrl触发-->
<!--以上两种形式都行-->
<input @keyup.17.67="doSomething" />
6. 系统修饰符
2.1.0新增
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
6.1 exact
修饰符
2.5.0新增
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
<!-- 只有 Ctrl 被按下不释放的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">B</button>
<!-- 没有任何按键被按住不释放的时候才触发 -->
<button @click.exact="onClick1">C</button>
@click.ctrl.exact
等同于@keyup.ctrl.67
,据我理解新增.exact
可能是为了区分开@keyup.ctrl.67
和@keyup.17.67
6.2鼠标按钮修饰符
.left
right
.middle
<!--鼠标左键-->
<button @click.left="onMouseLeft">D</button>
<!--Ctrl + 鼠标左键-->
<button @keyup.17.left="onMouseLeft">D</button>