返回

从源代码剖析 Vue 中 this 如何访问 Data 和 Methods

前端

前言

在 Vue 中,我们经常使用 this 来访问组件的 data 和 methods。但你有没有想过 this 究竟是如何做到这一点的呢?本文将带你深入 Vue 2.7 的源码,详细剖析 this 的访问机制,带你领略 Vue 的内部奥秘。

源码分析

1. 创建 Vue 实例

首先,我们从创建一个 Vue 实例开始:

const app = new Vue({
  data() {
    return {
      name: 'John Doe',
    };
  },
  methods: {
    greet() {
      console.log(`Hello, ${this.name}!`);
    },
  },
});

2. 编译模板

接下来,Vue 将编译模板,将 HTML 代码转换成渲染函数:

const render = function() {
  with(this) {
    return _c('div', { attrs: { "id": "app" } }, [_v("Hello, " + _s(name) + "!")]);
  }
};

注意,在渲染函数中,this 关键字被用作上下文对象,可以访问组件的 data 和 methods。

3. 实例化 Vue 组件

在编译模板后,Vue 将实例化 Vue 组件:

const vm = new Vue({
  render,
  data: app.data,
  methods: app.methods,
});

在这个过程中,组件的 data 和 methods 被赋值给了 vm 实例。

4. 挂载组件

最后,Vue 将组件挂载到 DOM 中:

vm.$mount('#app');

此时,组件已经被挂载到 DOM 中,并且可以访问它的 data 和 methods。

this 的访问机制

那么,this 究竟是如何访问 data 和 methods 的呢?答案就在 Vue 的原型链中。

Vue 实例继承自 Vue 类,该类定义了一个 _init 方法,负责初始化实例。在 _init 方法中,Vue 执行以下操作:

  1. 将组件的选项(包括 data 和 methods)合并到实例中。
  2. 给实例设置一个 _data 属性,指向 data 对象。
  3. 给实例设置一个 _methods 属性,指向 methods 对象。
  4. this 绑定到实例上。

这样,当我们访问 this.name 时,它实际上会沿着原型链搜索,直到找到 _data 属性,并返回 name 的值。同样,当我们访问 this.greet 时,它会搜索原型链,直到找到 _methods 属性,并返回 greet 方法的引用。

总结

通过深入剖析 Vue 2.7 的源码,我们了解了 Vue 中 this 的访问机制。Vue 通过原型链将 data 和 methods 绑定到实例上,使 this 能够访问这些属性和方法。这背后的原理简洁高效,让 Vue 能够以灵活而强大的方式管理组件状态。