vue 源码分析(尚硅谷视频学习笔记)

下面是我边看视频变记录的重点难点,详细具体有条理的看我转载的那篇尚硅谷课件,课件有的内容我基本不重复写到

1.类数组和数组

用document.getElementsByClassName()方法或者jQuery方法获取的标签集合是类数组,不是真正的数组。使用instanceof可以知道lis instanceof Object为true; lis instanceof Array为false。假如用lis接收,那么lis可以使用lis[index]的方式获取某一个标签对象,但是不可以使用Array(数组)原型链上的属性和方法。如forEach、splice、join等。

2.类数组使用forEach遍历所有标签对象(类数组转数组)

ES6: Array.from(lis)
ES5:[].slice.call(lis) 或者 Array.prototype.slice.call(lis)

3.节点类型(nodeType)

常用的:
Document
Element
Attribute
Text

node.nodeType获取节点类型(Number)

4.定义属性Object.defineProperty(obj, prop, descriptior)

在descriptior内定义set和get方法,可以实现属性的监听和获取。
IE8不支持此语法,此方法是Vue实现数据绑定等操作的核心方法。

属性描述符:

1.数据描述符:

configurable: true/false 是否可以重新define
enumerable: true/false 是否可以枚举(for…in / keys())
value: 指定初始值
writable: true/false value 是否可以修改

2.访问描述符:

get: 回调函数, 用来得到当前属性值
set: 回调函数, 用来监视当前属性值的变化

5.判断是否是自身属性(obj.hasOwnProperty(pro))

JS学过,返回布尔值。

6.DocumentFragment: 文档碎片(高效批量更新多个节点)

内存中保存n个element的容器对象(不与界面关联),如果更新fragment中的某个element,界面不变。
多次更新界面变成一次更新界面,减少更新界面的次数。

一个节点只能有一个父亲

使用步骤:

  1. 创建fragment
  2. 取出要更新的所有节点的父节点的所有子节点保存到fragment中(使用appendChild()方法)
  3. 更新fragment中的所有要更新节点的更新内容
  4. 将fragment插入更新节点的父节点

7.数据代理

vue 数据代理: 通过vm 对象来代理data 对象中所有属性的操作
vm._data.name === vm.name

8.set和get执行的断点调试

在这里插入图片描述
打断点后观察可知:
1.vm对象对data中的数据实现数据代理
2.vm中触发回调函数执行,函数中调用_propxy()方法,里面是用Object.defineProperty(obj, prop, descriptior)实现。
3.修改属性值调用Object.defineProperty(obj, prop, descriptior)中的descriptior对象中的set方法,数据被存入data。
4.页面中显示数据调用get方法从data中取数据。

9.大佬仿Vue的main.js

/*
相关于Vue的构造函数
 */
function MVVM(options) {
  // 将选项对象保存到vm
  this.$options = options;
  // 将data对象保存到vm和datq变量中
  var data = this._data = this.$options.data;
  //将vm保存在me变量中
  var me = this;
  // 遍历data中所有属性
  Object.keys(data).forEach(function (key) { // 属性名: name
    // 对指定属性实现代理
    me._proxy(key);
  });

  // 对data进行监视
  observe(data, this);

  // 创建一个用来编译模板的compile对象
  this.$compile = new Compile(options.el || document.body, this)
}

MVVM.prototype = {
  $watch: function (key, cb, options) {
    new Watcher(this, key, cb);
  },

  // 对指定属性实现代理
  _proxy: function (key) {
    // 保存vm
    var me = this;
    // 给vm添加指定属性名的属性(使用属性描述)
    Object.defineProperty(me, key, {
      configurable: false, // 不能再重新定义
      enumerable: true, // 可以枚举
      // 当通过vm.name读取属性值时自动调用
      get: function proxyGetter() {
        // 读取data中对应属性值返回(实现代理读操作)
        return me._data[key];
      },
      // 当通过vm.name = 'xxx'时自动调用
      set: function proxySetter(newVal) {
        // 将最新的值保存到data中对应的属性上(实现代理写操作)
        me._data[key] = newVal;
      }
    });
  }
};
<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值