vue中的事件绑定
目录
2.5 self只有event.target是当前的操作元素时才出发事件
2.6 passive事件的默认行为立即执行,无需等待事件回调执行完毕
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是新的别名。
一般不推荐自定义按键名。
更多推荐
所有评论(0)