Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

时间:2022-11-30 07:56:38

基本使用

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
}
},
});

页面效果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

点击按钮:弹框也没有问题;

原生JS里事件也会返回 event 对象,Vue也是可以,看控制台结果:

Vue2(笔记04) - 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);
}
},
});

看页面效果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

分别点击按钮:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符


问题:观察vm中的数据和函数有何不同?

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

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.");
},
},
});

看下效果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

连续点击 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.");
},
},
});

看下效果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符


需求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 会如何?

看效果和结果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

冒泡模式,由内向外;点击 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 会如何?

看效果和结果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

虽然点击的是 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);
},
},
});

看效果:

Vue2(笔记04) - Vue核心 - 事件处理-事件修饰符

点的是按钮,加上冒泡,就会输出两次 ​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 ,所以算了,不触发了;