我们已经知道在原生js中如何去绑定一个事件,那么在Vue中我们怎么实现事件绑定呢?
我们可以先来看一个最简单的例子:
我们点击一个按钮,出现一个弹窗显示你好CSDN。
<body>
<button id="root" v-on:click="show">点击我会有神奇的事情发生button>
body>
<script>
Vue.config.productionTip=false
new Vue({
el:'#root',
methods:{
show(){
alert('你好CSDN')
}
}
})
script>
v-
代表时Vue的指令,on
代表是什么时候,click
代表是点击的时候。满足条件则Vue执行回调函数,函数名作为值。函数体写在Vue实例对象的methods属性对象中。
这里我们有几个注意的点:
这个show方法会接受一个事件对象
show方法中的this是一个Vue实例。但是如果你使用的是箭头函数,他没有自己的this,就会向外部寻找,最后this就是window。
所有被Vue管理的函数(也就是Vue对象里面的函数)最好都使用普通函数
v-on:click
也有它的简写形式:@click
,所以上面的代码也可以写成:
这个回调函数也可以接受参数:
<body>
<div id="root">
<button v-on:click="show1">点击我会有神奇的事情发生button> <br>
<button v-on:click="show2(10)">点击我会有神奇的事情发生button>
div>
body>
<script>
Vue.config.productionTip=false
new Vue({
el:'#root',
methods:{
show1(){
alert('你好CSDN')
},
show2(num){
alert(num)
}
}
})
script>
在函数名之后加一个括号,传入参数即可。不过也会有一个问题:前面我们提到过Vue在调用回调函数的时候会传入一个事件对象,如果我们现在要使用它怎么办呢?
如果直接多创建一个形参是接收不到这个事件对象的。
我们这里需要用到一个占位符$event
例如:
<body>
<div id="root">
<button v-on:click="show1">点击我会有神奇的事情发生button> <br>
<button v-on:click="show2(10,$event)">点击我会有神奇的事情发生button>
div>
body>
<script>
Vue.config.productionTip=false
new Vue({
el:'#root',
methods:{
show1(){
alert('你好CSDN')
},
show2(num,event){
alert(num)
console.log(event);
}
}
})
script>
注意:
不过如果你把这个方法写在data中,方法可以正常回调,同时也会进行代理。(也就是说data里面的数据都会进行代理)当然我们不推荐这样写,会降低Vue的执行效率
最后总结一下:
事件的基本使用:
我们知道点击a标签会自动跳转到指定网址,如果我们现在不想让他执行这个默认行为,怎么办呢,有两种方法:
①在回调方法中,利用事件对象阻止默认行为:
<body>
<div id="root">
<a href="http://www.csdn.net" @click="show">点我显示信息a>
div>
body>
<script>
new Vue({
el:'#root',
methods:{
show(e){
e.preventDefault()
alert('你好CSDN')
}
}
})
script>
②使用事件修饰符
<body>
<div id="root">
<a href="http://www.csdn.net" @click.prevent="show">点我显示信息a>
div>
body>
<script>
new Vue({
el:'#root',
methods:{
show(){
alert('你好CSDN')
}
}
})
script>
像这样的事件修饰符还有:
prevent
:阻止默认事件(常用);stop
:阻止事件冒泡(常用);once
:事件只触发一次(常用);capture
:使用事件的捕获模式;self
:只有event.target是当前操作的元素时才触发事件;passive
:事件的默认行为立即执行,无需等待事件回调执行完毕;stop、once、passive在这里不做讲解。
capture:使用事件的捕获形式
我们知道在JS的事件流中分为捕获阶段
和冒泡阶段
,现在我们来看下面的两个嵌套的盒子:
如果我们给div1和div2均绑定了点击事件。那么在我们点击div2的时候,就会依次出现左边蓝色箭头的捕获阶段和右边红色箭头的冒泡阶段,我们可以知道真正的事件处理在冒泡阶段,最终的结果就是先触发div2的点击事件,再触发div1的点击事件。但是如果我们想在捕获阶段就处理事件呢?这个时候我们就可以使用capture事件修饰符,我们最后的结果变成为先触发div1的点击事件,再触发div2的点击事件。
注意:给谁加,谁的事件就在捕获阶段被处理。上面的那个例子中,我们应该给外面的盒子div1加capture修饰符.
self:只有event.target是当前操作的元素时才触发事件
我们还是提供一个场景:
如果我们现在点击按钮,会因为冒泡机制而依次触发button和div的事件。不过注意这两次事件的event.target都是button元素。
倘若我们现在给div加一个self修饰符,那么当冒泡到div的时候发现event.target不符合当前div元素,就不会触发事件,从另一个角度说我们可以利用这一点去阻止冒泡。
注意:事件修饰符可以叠加
例如:
@click.prevent.stop="showInfo"表示先阻止默认事件,再停止冒泡。
@click.prevent.stop="showInfo"表示先停止冒泡,再阻止默认行为。
不过最好不要与once叠加,容易出错
现在我们想在按下键盘上的enter键时触发事件。在原生js中我们可能需要去知道enter键的keycode,再利用条件判断来完成。但是现在Vue为我们提供了常用的按键别名是我们可以快速达成目标。
Vue中常用的按键别名:
那么我们如何去使用呢?
<div id="root">
<h2>欢迎来到CSDN学习h2>
<input type="text" placeholder="按下回车提示输入" @keydown.enter="showInfo">
div>
keydown和keyup是两个常用的键盘事件:
keyup是在按键按下回弹时触发
keydown是直接按下触发
如此在我们按下enter键的时候,事件就会被触发并执行相应的回调函数。
如果我们想在其他的按键上面绑定事件怎么办呢?
我们可以使用按键原始的key值去绑定,但注意要转化为kebeb-case(短横线命名)
举个例子:我们想给切换大小写的键绑定一个事件。那么我们就想知道切换大小写键的key值是多少,我们可以利用键盘事件对象的key属性去查询。
前面那一个就是key值,得到之后我们不能直接使用,还要转化为短横线命名法:caps-lock,再去使用就可以了。
<div id="root">
<h2>欢迎来到CSDN学习h2>
<input type="text" placeholder="按下回车提示输入" @keydown.caps-lock="showInfo">
div>
换行 => tab (特殊,必须配合keydown去使用)
因为tab键还有一个功能就是转换焦点。比如你选中了一个文本框,按下tab之后,文本框会失去焦点,呈现未选中的状态,此时的焦点已经它的身上转移了。
当你在按下tab的时候,还没有等他弹起来焦点就已经被切换了,这样事件就触发不了。所以要使用keydown去绑定才有用。
在这里有四个键较为特殊:系统修饰键(ctrl、alt、shift、meta)
meta键就是win键
拓展:如果我们想要按下ctrl+y时候才触发事件怎么办?
如果像下面这样:
<div id="root">
<h2>欢迎来到CSDN学习h2>
<input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo">
div>
那么我们使用ctrl+任意键都可以触发这个事件,显然不符合要求。我们可以这样写:
<div id="root">
<h2>欢迎来到CSDN学习h2>
<input type="text" placeholder="按下回车提示输入" @keydown.enter.y="showInfo">
div>
一般只有系统修饰键才会这么写
同时Vue还支持别名的定制:
Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
然后我们就可以使用了
<div id="root">
<h2>欢迎来到CSDN学习h2>
<input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
div>