在前两篇文章中,我们学习了Vue的基础概念和指令语法。今天我们来重点攻克Vue中的事件绑定------这是构建交互式应用的核心技能。本文将涵盖事件绑定的各种写法、参数传递、this指向以及底层实现原理。
一、Vue事件绑定基础
1. 事件绑定方式对比
原生JavaScript实现:
// 方式一:addEventListener
let btn1 = document.getElementById("btn1");
btn1.addEventListener("click", () => {
console.log("hello1");
});
// 方式二:onclick属性
btn1.onclick = function() {
console.log('hello2');
}
// 方式三:全局函数
function demo1() {
console.log("hello3");
}
Vue事件绑定:
<!-- 基本语法 -->
<button v-on:click="demo()">按钮</button>
<!-- 简写形式(推荐) -->
<button @click="demo()">按钮</button>
2. Vue事件绑定的注意事项
❌ 错误写法:
<!-- 错误:alert不是Vue实例管理的方法 -->
<button v-on:click="alert('hello')">按钮</button>
<!-- 错误:全局函数不会被Vue实例管理 -->
<button v-on:click="demo1()">按钮</button>
✅ 正确写法:
<!-- 在methods配置项中定义方法 -->
<button @click="demo()">按钮</button>
3. 事件参数传递
带参数的事件处理:
<!-- 传递自定义参数和事件对象 -->
<input type="text" @input="fun(1, 2, 3, $event)" />
<!-- 只传递事件对象(省略小括号) -->
<input type="text" @input="fun" />
对应的methods配置:
methods: {
fun(a, b, c, e) {
console.log(e.target.value); // 获取输入框的值
console.log(a, b, c); // 输出:1, 2, 3
}
}
4. 事件处理知识点总结
-
指令的语法格式 :
<标签 v-指令名:参数名="表达式">{{插值语法}}</标签>"表达式"位置可以写:常量、JS表达式、Vue实例所管理的XXX
-
事件绑定指令 :
v-on- 语法格式:
v-on:事件名="表达式" - 示例:
v-on:click="表达式"表示鼠标单击事件 - 示例:
v-on:keydown="表达式"表示键盘按下事件
- 语法格式:
-
配置项
methods:
所有事件所关联的回调函数,需要在Vue实例的配置项methods中进行定义。methods是一个对象,可以定义多个回调函数。 -
v-on简写形式 :v-on:click→@clickv-on:keydown→@keydownv-on:mouseover→@mouseover
-
小括号省略规则 :如果函数调用时不需要传递任何参数,小括号
()可以省略。默认传递事件对象event。 -
自动传递事件对象:Vue在调用回调函数时,会自动给回调函数传递当前发生的事件对象。
-
$event占位符 :在绑定回调函数时,可以使用$event占位符,Vue会自动将当前事件对象传过去。
二、事件回调函数中的this指向
1. Vue的承诺
- 承诺1 :只要
data中的数据发生变化,自动更新所有用到该数据的地方 - 承诺2 :模板语句中可以直接拿到
vm身上的数据,不需要vm.或this.
2. this指向问题
普通函数写法(推荐):
methods: {
add() {
this.num++; // this指向Vue实例
console.log(this); // 当前的Vue实例对象
this.fun(); // 可以调用其他方法
}
}
👉 常规写法下,回调函数中的 this 是 vm(Vue实例)
箭头函数写法(不推荐):
methods: {
add2: () => {
console.log(this); // window对象
// 无法正确访问data中的数据
}
}
⚠️ 箭头函数没有自己的 this,它的 this 是继承来的,默认指向定义时的上下文。由于对象不能构成单独的作用域,父级作用域是全局作用域,也就是 window。
3. 异步操作中的this
可以在函数中改变 data 中的数据,例如 this.num++,这会联动页面上产生动态效果。
methods: {
add3() {
setTimeout(() => {
this.num++; // 箭头函数继承外层this,指向Vue实例
}, 2000);
}
}
💡 最佳实践 :在异步操作(如 setTimeout、axios 请求)中,推荐使用箭头函数保持 this 指向。
三、methods实现原理
1. 简易实现
class MyVue {
constructor(options) {
// 将methods中的方法挂载到实例上
for (const key in options.methods) {
this[key] = options.methods[key];
}
}
}
const vm = new MyVue({
data() {
return {
msg: "hello vue!"
};
},
methods: {
fun1() { console.log("fun1"); },
fun2() { console.log("fun2"); },
fun3() { console.log("fun3"); }
}
});
vm.fun1(); // 可以正常调用
2. Vue实际实现特点
methods中的方法通过数据代理挂载到Vue实例- 方法中的
this被自动绑定到Vue实例 - 可以通过
vm直接访问methods中的方法
四、重点总结
1. 事件绑定语法
| 写法 | 示例 | 说明 |
|---|---|---|
| 完整写法 | v-on:click="handler" |
标准语法 |
| 简写形式 | @click="handler" |
推荐使用 |
2. 参数传递规则
| 场景 | 写法 | 说明 |
|---|---|---|
| 需要自定义参数 | @click="fun(param1, param2, $event)" |
使用 $event 占位符 |
| 只需要事件对象 | @click="fun" |
可省略小括号 |
3. this指向规则
| 函数类型 | this指向 | 推荐度 |
|---|---|---|
| 普通函数 | Vue实例(vm) | ✅ 推荐 |
| 箭头函数 | 定义时的上下文(通常为window) | ❌ 不推荐 |
| 异步回调中的箭头函数 | 继承外层this(Vue实例) | ✅ 推荐 |
4. 最佳实践
- ✅ 事件处理方法统一在
methods中定义 - ✅ 使用普通函数 确保正确的
this指向 - ✅ 需要事件对象时使用
$event参数 - ✅ 异步操作中使用箭头函数保持
this指向
掌握了事件绑定,你的Vue应用就有了交互的灵魂。下一篇文章我们将继续学习修饰符、计算属性和侦听器,敬请期待!