【源码共读】- Vue2 中 this 能够直接获取到 data 和 methods源码解析

84 阅读2分钟

1.提出问题

  1. 如何调试源码
  2. vue中为什么this能直接获取到data和methods中的数据和方法
  3. 如何应用到实际中

2.如何调试源码

使用了 UNPKG(在线获取vue源码资源) 和 http-server(本地启动服务调试源码)

2.1 UNPKG

image.png 如上图官网截图,大致意思是一个基于npm的静态资源服务,可以从npm库中获取任何包,无需下载本地,用url就能直接使用。

2.2 http-server

image.png 如上官网截图,这是一个零配置的静态服务,便于生产和使用,用于本地测试和开发。源码调试需要全局安装npm i -g http-server,以此启动服务调试源码。

2.3 具体步骤

详细拓展 断点调试debugger

  1. 本地新建一个文件夹,包括index.html
  2. 在body标签中加上行内js
  3. 全局安装npm i -g http-server
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
  <script>
     const vm = new Vue({
      data: {
        name: '老师是若川',
      },
      methods: {
        sayName(){
          console.log(this.name);
        }
      },
    });
    console.log(vm.name);
    console.log(vm.sayName());
  </script>
</body>
</html>
  1. 如何进入源码

    在新建的文件夹下打开终端,输入http-server .,会给到本地调式的端口,若端口号被占用,http-server . -p 指定的端口号,进入浏览器F12对应的sources

  2. 如何打断点调试

    image.png 拓展:断点调试debugger

3.源码解读

3.1 Vue构造函数

if (!(this instanceof Vue)是什么,与jQuery源码new的区别

3.2 _init初始化函数,找出data和methods能获取的源头

  1. 全局搜索initMixin函数并观察initState方法,Ctr+F全局搜索找到
  2. initState中有对methods和data初始化的方法,重点来看初始化 methods,之后再看初始化 data
  3. initMethods
    • 共三个判断,第三个不懂【判断 methods 中的每一项是不是已经在 new Vue实例 vm 上存在,而且是方法名是保留的 _ $ (在JS中一般指内部变量标识)开头,如果是警告。】
    • 判断通过之后,vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);=>initMethods函数其实就是遍历传入的methods对象,并且使用bind绑定函数的this指向为vm,也就是new Vue的实例对象。
    • 关注bind变量,鼠标移入 alt键有提示218行,直接点击image.png
    • 跳到了polyfillBind函数,返回了一个函数,用于修改this指向,注意看若川的说明
    • 使用callapply实现,据说是因为性能问题。

4. initData

关注initData函数做的七步,重点关注:

-   getData函数如何获取数据
-   proxy代理函数 `this.xxx为什么访问的是 this._data.xxx`
    -   proxy函数核心 `Object.defineProperty`,六个属性[拓展](https://juejin.cn/post/6994976281053888519#heading-34)

5. 以上函数常出现的公共函数

-  hasOwn
-  isReserved

6. 若川精华:用60行代码实现简易版