深入解析Vue2中的this指代:场景、原理与对比 (二)

94 阅读2分钟

在 Vue2 中,<button v-on:click="cli(this)"> 这种写法中的 this 并不是指向 Vue 实例,而是指向 当前 DOM 元素(即 <button> 元素本身)。这是因为在模板中直接使用 this 时,Vue 并不会将其绑定到 Vue 实例,而是将其作为普通的 JavaScript 代码解析。


详细解析

1. this 的指向

在以下代码中:

<template>
  <button v-on:click="cli(this)">点击</button>
</template>

<script>
export default {
  methods: {
    cli(el) {
      console.log(el); // 输出:<button>点击</button>
    }
  }
};
</script>
  • this 的指向this 指向的是当前 DOM 元素(即 <button> 元素)。
  • 原因:在模板中,this 并没有被 Vue 特殊处理,而是直接作为参数传递给了 cli 方法。

2. 正确访问 Vue 实例的方式

如果你希望在事件处理函数中访问 Vue 实例,应该直接调用方法,而不是传递 this。Vue 会自动将事件处理函数绑定到 Vue 实例。

正确写法:
<template>
  <button v-on:click="cli">点击</button>
</template>

<script>
export default {
  methods: {
    cli() {
      console.log(this); // 输出:Vue 实例
    }
  }
};
</script>
  • this 的指向this 指向 Vue 实例。
  • 原因:Vue 在编译模板时,会将 cli 方法绑定到 Vue 实例。

3. 如果需要访问 DOM 元素

如果你确实需要访问触发事件的 DOM 元素,可以使用 Vue 的 事件对象 $event

示例:
<template>
  <button v-on:click="cli($event)">点击</button>
</template>

<script>
export default {
  methods: {
    cli(event) {
      console.log(event.target); // 输出:<button>点击</button>
      console.log(this); // 输出:Vue 实例
    }
  }
};
</script>
  • event.target:指向触发事件的 DOM 元素。
  • this:仍然指向 Vue 实例。

4. 对比表格

写法this 指向说明
<button @click="cli(this)">DOM 元素(<button>this 作为参数传递时,指向 DOM 元素。
<button @click="cli">Vue 实例Vue 自动将方法绑定到实例,this 指向 Vue 实例。
<button @click="cli($event)">Vue 实例$event 是事件对象,event.target 指向 DOM 元素,this 指向实例。

5. 常见误区

  • 误区 1:认为模板中的 this 会自动指向 Vue 实例。
    事实:只有在 Vue 管理的上下文中(如 methodscomputed、生命周期钩子等),this 才会指向 Vue 实例。
  • 误区 2:在模板中直接传递 this 可以访问 Vue 实例。
    事实:模板中的 this 是普通的 JavaScript 代码,不会自动绑定到 Vue 实例。

6. 最佳实践

  • 访问 Vue 实例:直接调用方法,不要传递 this

    <button @click="cli">点击</button>
    
  • 访问 DOM 元素:使用 $event 获取事件对象。

    <button @click="cli($event)">点击</button>
    
  • 避免在模板中直接使用 this:除非你明确知道它的行为。


7. 代码示例总结

<template>
  <div>
    <!-- 错误写法:this 指向 DOM 元素 -->
    <button @click="cli(this)">错误写法</button>

    <!-- 正确写法:this 指向 Vue 实例 -->
    <button @click="cli">正确写法</button>

    <!-- 访问 DOM 元素:使用 $event -->
    <button @click="cli($event)">访问 DOM 元素</button>
  </div>
</template>

<script>
export default {
  methods: {
    cli(event) {
      console.log('this:', this); // Vue 实例
      console.log('event.target:', event && event.target); // DOM 元素
    }
  }
};
</script>

Summary

  • <button @click="cli(this)"> 中的 this:指向 DOM 元素(<button>)。
  • 正确访问 Vue 实例的方式:直接调用方法,不要传递 this
  • 访问 DOM 元素的方式:使用 $event 获取事件对象。