- ✨本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与
- 🎃这是2021-09-23的源码共读,🧭 学习链接
1.提出问题
- 如何调试源码
- vue中为什么this能直接获取到data和methods中的数据和方法
- 如何应用到实际中
2.如何调试源码
使用了 UNPKG(在线获取vue源码资源) 和 http-server(本地启动服务调试源码)
2.1 UNPKG
如上图官网截图,大致意思是一个基于npm的静态资源服务,可以从npm库中获取任何包,无需下载本地,用url就能直接使用。
2.2 http-server
如上官网截图,这是一个零配置的静态服务,便于生产和使用,用于本地测试和开发。源码调试需要全局安装
npm i -g http-server,以此启动服务调试源码。
2.3 具体步骤
详细拓展 断点调试debugger
- 本地新建一个文件夹,包括index.html
- 在body标签中加上行内js
- 全局安装
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>
-
如何进入源码
在新建的文件夹下打开终端,输入
http-server .,会给到本地调式的端口,若端口号被占用,http-server . -p 指定的端口号,进入浏览器F12对应的sources。 -
如何打断点调试
3.源码解读
3.1 Vue构造函数
if (!(this instanceof Vue)是什么,与jQuery源码new的区别
3.2 _init初始化函数,找出data和methods能获取的源头
- 全局搜索initMixin函数并观察initState方法,Ctr+F全局搜索找到
- initState中有对methods和data初始化的方法,重点来看初始化
methods,之后再看初始化data - 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行,直接点击
- 跳到了polyfillBind函数,返回了一个函数,用于修改this指向,注意看若川的说明
- 使用
call和apply实现,据说是因为性能问题。
4. initData
关注initData函数做的七步,重点关注:
- getData函数如何获取数据
- proxy代理函数 `this.xxx为什么访问的是 this._data.xxx`
- proxy函数核心 `Object.defineProperty`,六个属性[拓展](https://juejin.cn/post/6994976281053888519#heading-34)
5. 以上函数常出现的公共函数
- hasOwn
- isReserved