基本使用
Vue里的事件基本应用;
需求1,点击按钮提示信息:
<div id="root">
<h2>welcome, {{name}}</h2>
<button v-on:click = "showInfo">点我提示信息</button>
</div>
v-on:click="showInfo"
是Vue绑定事件的指令语法;
意思是:当点击这个 btn 的时,调用 showInfo 函数,事件函数也叫方法,所以写在 methods 里;
const vm = new Vue({
el: "#root",
data: {
name: "jack"
},
methods: {
showInfo(e){
alert('nice to meet you.');
console.log(e);
console.log(e.target);
console.log(e.target.innerText);
console.log(this); // 此处的 this 是vm
console.log(this === vm); // this 指向 vm
}
},
});
页面效果:
点击按钮:弹框也没有问题;
原生JS里事件也会返回 event 对象,Vue也是可以,看控制台结果:
分别是:事件对象,点击对象,对象文本,this对象和this指向的 vm;
注意:
这里使用了普通函数,没有使用箭头函数,showInfo:(e)=>{}
;
是因为箭头函数里没有自己的 this ,会指向 window ;普通函数里的 this 指向 Vue 实例对象;
所以,接受 Vue 管理的函数,一般都写成普通函数就行,showInfo(){}
;
需求2:点击按钮传递参数;
<div id="root">
<h2>welcome, {{name}}</h2>
<button @click="showInfo1">点我(不传参)</button>
<button @click="showInfo2($event,66)">点我(传参)</button>
</div>
注意1:绑定事件函数 v-on:click
可以简写成: @click
;
注意2:传递参数的时候,需要保留关键字 $event
,不写就接收不到了;其他参数写后边就行;
const vm = new Vue({
el: "#root",
data: {
name: "jack"
},
methods: {
showInfo1(e) {
console.log("nice to meet you.");
},
showInfo2(e, index) { // 默认接收 event 事件对象参数,和其他参数;
console.log(e.target);
console.log("@index:", index);
}
},
});
看页面效果:
分别点击按钮:
问题:观察vm中的数据和函数有何不同?
name 是做了数据代理,来自 _data,用来绑定数据的,是有可能会变化的;
函数是不用做数据代理的,因为函数是直接拿来使用的方法,不用修改;
【事件的基本使用】:
1)使用 v-on:xxx
或 @xxx
绑定事件,其中 xxx 是事件名;
2)事件的回调需要配置在 methods 对象中,最终会在 vm 上;
3)methods 中配置的函数,不要使用箭头函数!否则 this 就不是 vm 了;
4)methods 中配置的函数,都是被 Vue 所管理的函数,this 的指向是 vm 或组件实例对象;
5)@click="demo"
和 @click="demo($event)"
效果一样,但后者可以传参;
事件修饰符
需求1:阻止默认行为
<div id="root">
<h2>welcome, {{name}}</h2>
<a :href="url" @click.prevent="showInfo">{{webSite}}</a>
</div>
提示:之前讲过,绑定数据v-bind:
可以简写 :
;
提示:绑定事件,使用 v-on:click
可以简写成 @click
;
注意: prevent
是阻止默认行为的关键字,用链式写法跟在绑定事件后,在这里是阻止 a 跳转;
像 prevent 这种关键字,在 Vue 里叫修饰符,共有6个,见总结;
const vm = new Vue({
el: "#root",
data: {
name: "jack",
webSite:"51CTO",
url:"https://www.51cto.com"
},
methods: {
showInfo(e) {
// e.preventDefault(); // 原生JS里阻止默认行为的语句;
console.log("nice to meet you.");
},
},
});
看下效果:
连续点击 a 标签,不会跳转,还能在控制台正常输出;
【Vue中的事件修饰符】:
1)prevent :阻止默认事件(常用);
2)stop:阻止事件冒泡(常用);
3)once:事件只触发一次(常用);
4)capture:使用事件的捕获模式;
5)self:只有 event.target 是当前操作的元素时才触发事件;
6)passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
需求2:阻止事件冒泡
<div id="root">
<h2>hi, {{name}}</h2>
<div class="demo" @click="showInfo">
<button @click.stop="showInfo">点击欢迎</button>
</div>
</div>
外层 div 加了点样式,在这里省略了;
提示:button 和 外层的 div 都有绑定事件,点击按钮会触发冒泡;
注意:在绑定事件 @click
后,跟 stop
修饰符,可阻止按钮冒泡;
const vm = new Vue({
el: "#root",
data: {
name: "jack",
},
methods: {
showInfo(e) {
// e.stopPropagation(); // 原生JS阻止冒泡
console.log("nice to meet you.");
},
},
});
看下效果:
需求3:事件只触发一次
有时,点了一次,事件触发,再点一次就不希望再触发了;
<div id="root">
<h2>hi, {{name}}</h2>
<div class="demo" @click="showInfo">
<button @click.once="showInfo">点击欢迎</button>
</div>
</div>
直接使用上面的代码,只需要修改 修饰符 为 once
即可;
需求4:使用事件的捕获模式
事件的捕获是由外向内,事件的冒泡是由内向外,事件的触发顺序是先捕获后冒泡;
事件的默认模式是冒泡,要修改事件的默认模式,就需要添加 修饰符;
<div id="root">
<h2>hi, {{name}}</h2>
<div class="box1" @click="showMsg('div1')">div1
<div class="box2" @click="showMsg('div2')">div2</div>
</div>
</div>
提示:当前是两个嵌套的 div ,都绑定了事件,再没做修饰符的情况下,事件是冒泡模式;
const vm = new Vue({
el: "#root",
data: {
name: "jack",
},
methods: {
showMsg(msg) {
console.log(msg);
},
},
});
在未加 修饰符 的情况下,点击 div2 会如何?
看效果和结果:
冒泡模式,由内向外;点击 div2 ,那 div2 先触发,冒泡到 div1 ,所以输出顺序是如结果所示;
现在,加个事件捕获模式的修饰符:
<div id="root">
<h2>hi, {{name}}</h2>
<div class="box1" @click.capture="showMsg('div1')">div1
<div class="box2" @click="showMsg('div2')">div2</div>
</div>
</div>
注意:给 div1 加上了 开启事件捕获 模式的修饰符 capture
后,那 div1 就变成了捕获模式;
这时,再点击 div2 会如何?
看效果和结果:
虽然点击的是 div2 ,但因为 div1 开启了捕获模式,所以由外向内先触发,之后才是 div2 的冒泡模式被触发;
需求5:只有 event.target 是当前操作的元素时才触发事件
<div id="root">
<h2>hi, {{name}}</h2>
<div class="demo" @click="showInfo">
<button @click="showInfo">欢迎你</button>
</div>
</div>
没有绑定修饰符,点击按钮会触发事件冒泡。
const vm = new Vue({
el: "#root",
data: {
name: "jack",
},
methods: {
showInfo(e) {
console.log(e.target);
},
},
});
看效果:
点的是按钮,加上冒泡,就会输出两次 e.target
;
要的是 e.target 的触发事件,那不是 e.target 的就不会触发了,所以把 selft
修饰符绑给外层 div。
<div id="root">
<h2>hi, {{name}}</h2>
<div class="demo" @click.self="showInfo">
<button @click="showInfo">欢迎你</button>
</div>
</div>
绑给外层 div ,点击按钮后,执行 showInfo ,冒泡到上层 div ,div 一看,不是当前 e.target ,所以算了,不触发了;