vue中的事件绑定举例详解
作者:可乐暴暴子
1 事件处理
1.1 最简单的事件绑定例子
在vue当中,要给元素绑定事件需要用到vue指令,指令一般以v-开头,例如绑定单击事件的指令是v-on:click = “函数名”,简写为@click = “函数名”
例如以下例子:单击button按钮,执行showInfo函数,弹出alert窗口。
<body> <button class="btn" v-on:click = "showInfo">点击弹出{{name}}窗口</button> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ data:{ name:"alert" }, methods:{ showInfo(){ alert('hello!'); } } }) vm.$mount('.btn') </script> </body>
以上是最简单的事件绑定例子,鼠标悬停、鼠标移出等事件可以参照以上例子。
vm.$mount(".btn")指定了可供vue操作的元素,与el关键字的作用类似,但比el更加灵活。
methods记录了所有的方法,凡事与vue所操作元素有关的方法都应该写在method里面,否则无效。
在button属性里面,使用v-on:click绑定了一个单击事件,当点击此对象时,就执行showInfo函数。
1.2 默认参数event
这一步是探究methods配置项中,函数的传参问题。在上一个例子当中,设置了showInfo函数,这是自定义的函数,现在探究这个函数它默认情况下怎么接收函数。首先,为showInfo设置三个参数的位置,分别为a,b,c,然后后台输出a,b,c这三个参数,看看哪一个参数里面存的有东西。代码如下所示:
<body> <button class="btn" v-on:click = "showInfo">点击弹出{{name}}窗口</button> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ data:{ name:"alert" }, methods:{ showInfo(a,b,c){ alert('hello!'); console.log(a,b,c); } } }) vm.$mount('.btn') </script> </body>
可以发现输出的a,b,c当中只有a有东西,其他的全部为undefined。可以发现a里面存放的是一个名为PointerEvent(百度翻译:指针事件)的对象,其实就是事件对象event,有点像事件委托当中的event。可以尝试以下代码。
methods:{ showInfo(event){ alert('hello!'); console.log(event.target); console.log(event.target.innerHTML); } }
输出结果:分别弹出被点击的标签、被点击标签的文本内容。
1.3 其它自定义参数
先写好两个按钮,这两个按钮点击之后会触发相应的函数,btn1触发showInfo1函数,btn2触发showInfo2函数,showInfo1不传参数,showInfo2传入一个参数。接着,在methods中配置好showInfo1与showInfo2函数。代码如下所示:
<body> <button class="btn" v-on:click = "showInfo1">按钮1</button> <button class="btn" v-on:click = "showInfo2(66)">按钮2</button> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods:{ showInfo1(a){ console.log( `showInfo1:${a}`); }, showInfo2(a){ console.log( `showInfo2:${a}`); } } }) vm.$mount('.btn') </script> </body>
输出结果:
showInfo1没有传入任何参数,所以showInfo1的第一次参数位默认为event ,showInfo2我们给它传入了数字66作为第一个参数,所以showInfo2输出66 ,但这样做之后,event消失了。解决办法,再传入一个$event参数,$event是一个关键字,vue会自动将其解析为event,这个参数无论作为第几个参数都可以。代码如下所示:
<body> <div class="btns"> <button v-on:click = "showInfo1">按钮1</button> <button v-on:click = "showInfo2(66,$event)">按钮2</button>//添加$evetn </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods:{ showInfo1(a){ console.log( `showInfo1:${a}`); }, showInfo2(a,b){//增加形参b console.log( `showInfo2:${a},${b}`); } } }) vm.$mount('.btns') </script>
输出结果:
1.4 this
methods中的配置函数,都是被vue所管理的函数,this指向vm或组件实例对象,所以showInfo中的this指向vue实例(即例子当中的vm),若showInfo使用箭头函数,则this指向window。箭头函数的写法如下所示:
methods:{ showInfo:(event) => { alert('hello!'); console.log(event.target); console.log(event.target.innerHTML); } }
受vue所管理的函数最好写成普通函数,而不是写成箭头函数,不然会影响this的指向。
2 事件修饰符
2.1 prevent阻止默认事件(常用)
一般用在有默认事件的标签上,例如点击a标签时的默认跳转行为,写法是@click.prevent="函数名"
2.2 stop阻止事件冒泡(常用)
例如在以下代码当中,若先将button元素中的v-on:click.stop="showInfo1"改写为v-on:click="showInfo1",那么此时点击button按钮会弹出两次alert窗口。为什么?因为button元素和它的父级元素都有click事件,所以,如果点击button按钮不仅会触发button的单击事件,同时也会触发div的click事件,这种行为叫做冒泡,若在button元素中的单击事件中添加stop事件修饰符,那么会在button元素这一步停止冒泡行为。
<body> <div v-on:click="showInfo1" class="btns"> <button v-on:click.stop="showInfo1">按钮1</button> </div> <script type="text/javascript"> const vm = new Vue({ methods: { showInfo1() { alert(`弹出信息!`); } } }) vm.$mount('.btns') </script> </body>
2.3 once事件只触发一次(常用)
以上面的代码为例,每一次点击button都会出现alert弹窗,如果我想让它在第一次点击的时候出现弹窗,以后无论点多少从都不出现弹窗,该怎么做。
只需将button的单击事件改写为v-on:click.once='showInfo1'即可。
2.4 capture使用事件的捕获模式
捕获(由外往内),冒泡(由内往外),先捕获再冒泡,程序默认在冒泡阶段处理事件。
capture可以使程序在捕获阶段就开始处理事件。
首先观察以下不加任何修饰符的代码。
<body> <div v-on:click="showInfo1(1)" class="btns"> div1 <div v-on:click="showInfo1(2)"> div2 </div> </div> <script type="text/javascript"> const vm = new Vue({ methods: { showInfo1(number) { console.log(`${number}`); } } }) vm.$mount('.btns') </script> </body>
代码的大致意思是:我点击哪一个div元素就在控制台输出它的序号,观察它的输出顺序。若点击div1,则后台只输出1,若点击div2,则后台就接着输出2、1(有先后顺序),为什么点击div2的时候还要多输出1呢?因为默认使用了事件的冒泡模式,事件处理函数默认在冒泡阶段被执行。现在我想让div1在捕获阶段就被执行,那么只需要在div的单击事件上添加capture事件修饰符即可。代码示例如下:
<body> <div v-on:click.capture="showInfo1(1)" class="btns"> div1 <div v-on:click="showInfo1(2)"> div2 </div> </div> <script type="text/javascript"> const vm = new Vue({ methods: { showInfo1(number) { console.log(`${number}`); } } }) vm.$mount('.btns') </script> </body>
此时若再来点击div2,则控制台弹出1、2(有先后顺序),与刚才的截然相反。
但有一个误区值得注意,div1的事件是在捕获阶段被触发的,div2的事件仍然是在冒泡阶段触发的,简单总结就是有capture的事件才会在捕获阶段触发,没有capture的事件仍然在冒泡阶段被触发,这一点可以通过以下例子被证实:
<body> <div v-on:click.capture="showInfo1(1)" class="btns"> div1 <div v-on:click="showInfo1(2)"> div2 <div v-on:click="showInfo1(3)"> div3 </div> </div> </div> <script type="text/javascript"> const vm = new Vue({ methods: { showInfo1(number) { console.log(`${number}`); } } }) vm.$mount('.btns') </script> </body>
观察代码发现,只有div1有capture,所以当点击div3的时候,控制台先后输出1、3、2。
2.5 self只有event.target是当前的操作元素时才出发事件
这个2.5的标题可能有点难以理解,首先来看看event.target是什么。先来个例子:
<body> <div v-on:click="showInfo2" class="btns"> div <span v-on:click="showInfo1"> span </span> </div> <script type="text/javascript"> const vm = new Vue({ methods: { showInfo1(event) { console.log(`我是span我点击的是${event.target}`); }, showInfo2(event) { console.log(`我是div我点击的是${event.target}`); } } }) vm.$mount('.btns') </script> </body>
以上代码大致意思是,若点击div则执行showInfo1,若点击span则执行showInfo2。
若点击div,则后台输出情况如下:这一条结果对应的是div标签的事件,且从语句中我们可得知被点击的是div标签。
若点击span,则后台输出情况如下:因为冒泡输出了两个结果,但从两条结果中都可获知被点击的是span标签。
所以,综上所述,event.target代表被点击的对象,无论当前被捕获(或冒泡)到哪一个元素,event.target的值都不变。
再次回到self事件修饰符,只有self的作用对象与event.target目标对象是同一个时,事件才被执行。以下是示例代码:(在第二行添加了self)
<body> <div v-on:click.self="showInfo2" class="btns"> div <span v-on:click="showInfo1"> span </span> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods: { showInfo1(event) { console.log(`我是span我点击的是${event.target}`); }, showInfo2(event) { console.log(`我是div我点击的是${event.target}`); } } }) vm.$mount('.btns') </script> </body>
这时候点击span就不会出现两条结果了,而是只出现“我是span我点击的是[objectHTMLSpanElement]”。
为什么这时候只有一条语句呢,因为点击span后,代码首先执行span的事件,然后再冒泡到div,发现div有self,但event.target的并不是div,所以div的事件就没有执行。若直接点击div,则div的事件正常执行。
2.6 passive事件的默认行为立即执行,无需等待事件回调执行完毕
事件的默认行为就例如:a标签点击会跳转、鼠标轮滚动页面也会滚动等等。
@scroll是滚动条滚动事件,@wheel是鼠标滚轮滚动事件,两者有区别。
passive一般用在什么情况?(如下)
以鼠标滚动事件为例,当不考虑passive时,并且设置了滚动时需要执行函数的机制时,执行顺序是:
触发滚动事件——执行滚动时的函数——页面滚动
以上顺序需要等待函数执行完毕页面才能滚动,若所执行的函数耗时非常大,就会造成卡顿现象。
面对此现象,如果加上passive事件修饰符,那么函数和默认事件就会同时执行,且不会造成页面卡顿现象。
2.7 事件修饰符的连续使用
如果既需要阻止冒泡,又需要阻止默认跳转行为,则写法应如下:
@click.stop.prevent = "函数名"或者@click.prevent.stop = "函数名",两种写法任选其一,效果一致。
3 键盘事件
3.1 Vue中常用的按键别名
- 回车 => enter
- 删除 => delete
- 退出 => esc
- 空格 => space
- 换行 => tab
- 上 => up
- 下 => down
- 左 => left
- 右 => right
Vue当中未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.2 最简单的绑定键盘事件的方法
键盘事件常用的有两个:keydown(键盘按下时执行)和keyup(键盘按下后弹起时执行)
绑定键盘事件的写法为@keyup="函数名"(v-on:keyup="函数名"),可参照以下代码。
每一个按键都有自己的名字与编码,以下代码执行的是 在按下任意键之后,控制台显示该按键的按键名(key)与按键编码(keyCode)。keyCode在web标准中已经被废弃
<body> <div class="btns"> <input type="text" @keyup="keyEvent"> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods: { keyEvent(event) { console.log(event.key,event.keyCode); } } }) vm.$mount('.btns') </script> </body>
以下例举几个按键:
注意:这里输出的结果开头大写,并非vue当中所提供的别名,vue提供的别名一般用在形如@keyup.enter=“函数名” 上,后面会有详细描述。
3.3 按下目标键才触发的键盘事件
假如现在有一个input标签,在input标签中输入内容,输入完毕后,只有按回车键才能将输入的内容显示在控制台。有两种实现方法:
第一种:使用if进行原始的按键判断方法
<body> <div class="btns"> <input type="text" @keyup="keyEvent"> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods: { keyEvent(event) { if (event.key == 'Enter') { console.log(event.target.value); } } } }) vm.$mount('.btns') </script> </body>
第二种:使用vue提供的按键判断(要用到vue提供的别名),只需在@keyup后添加别名即可。
<body> <div class="btns"> <input type="text" @keyup.enter="keyEvent"> </div> <script type="text/javascript"> Vue.config.productionTip = false; const vm = new Vue({ methods: { keyEvent(event) { console.log(event.target.value); } } }) vm.$mount('.btns') </script> </body>
但是有一类按键比较特殊,这类按键由多个单词组成,例如CapsLock(大小写切换),它由Caps与Lock组成,写在@keyup后面就应该这样写:
@keyup.caps-lock="函数名"
即:将两个单词拆分开用短横线连接,并且将大写字母变为小写。
另外一个需要注意的点是,部分按键无法进行键盘事件的绑定,例如音量键、亮度键等。
3.4 tab按键(特殊)
tab按键自身就有一个功能,就是把焦点从当前元素身上移到另一个元素身上。tab键在按下但还没有抬起来时就已经被触发,所以@keyup对tab键无效,需要使用@keydown来控制tab键。
3.5 系统修饰键(特殊)
系统修饰键(用法特殊):ctrl、shift、alt、meta(也叫徽标键或win键)。
以上按键需要配合keydowm按键才能正常的触发键盘事件。若配合keyup按键,则需要再按下修饰键的同时再按下其他键,随后释放其他键,事件才被触发。
若规定只能按下ctrl+y才能触发键盘事件,应该怎么写?
答案:@keyup.ctrl.y = "函数名"
3.6 自定义按键别名
例如将回车键的别名由enter改为huiche需要怎么改?
写法如下:
vue.config.keyCodes.huiche = 13;
数字13是回车键的编码。huiche是新的别名。
一般不推荐自定义按键名。
总结
到此这篇关于vue中的事件绑定的文章就介绍到这了,更多相关vue事件绑定内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!