博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小白的进阶之路之vue源码解读(1)
阅读量:6412 次
发布时间:2019-06-23

本文共 4311 字,大约阅读时间需要 14 分钟。

vue源码解读(1)

前言

小白最近也被vue源码折腾的头疼不已,小白打算把自己学习vue源码的思路说出来,如有错误的地方,请务必留言指正,让小白能在前端的道路上更进一步。如果喜欢、批评、指正、或者你有更多的想法,不妨点个,或者评论留言谢谢?。

本系列基于vue2.0.0 探讨

接下来写多少章说实话小白自己也不是很清楚,小白也不是完全学明白了然后过来给大家描述,在这里只是记录了一些小白学习的过程。最近这些天一直想着看源码,结合网上的一些文章,发现根本看不懂啊。比如说Object​.defineProperty()Mixin模式flow.js此处省略1万字。。。。看了半天还是云里雾里。我觉得想完完全全看懂源码,首先得知道一些扩充的知识,先把这些知识补充上吧。不过今天想说的并不是跟上面那些有关的,我觉得在看源码之前应该先了解一下vue具体运行过程,它到底是怎么样来执行的。

参考了掘金小册

响应式系统基本原理

在前面一章我们说过,响应式系统最核心的部分就是这个Object.defineProperty(obj, prop, descriptor) 定义:

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

描述:

该方法允许精确添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys 方法), 这些属性的值可以被改变,也可以被删除。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改的。

我们来解释一下这些参数分别是有什么用

Object.defineProperty(obj, prop, descriptor)        obj        要在其上定义属性的对象。        prop        要定义或修改的属性的名称。        descriptor        将被定义或修改的属性描述符。返回值为:   被传递给函数的对象。复制代码

descriptor属性描述符

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者.

数据描述符存取描述符均具有以下可选键值:

  1. configurable 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
  2. enumerable 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。

数据描述符同时具有以下可选键值:

  1. value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
  2. writable 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。

存取描述符同时具有以下可选键值:

  1. get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。 默认为 undefined。
  2. set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。 默认为 undefined。

当然 这是MDN的原话啦 总结一下有以下几种:

  • enumerable,属性是否可枚举,默认 false。
  • configurable,属性是否可以被修改或者删除,默认 false。
  • writable,value是否可被修改,默认false。
  • value, 该属性对应的值。
  • get,获取属性的方法。
  • set,设置属性的方法。

封装一个myVue

var app = new myVue({      el:'#app',      data: {        number: 0      },    })复制代码
  1. 定义一个myVue
function myVue(options) {  }复制代码

想想我们之前说的那个步骤,接下来该进行初始化,获取到data

function myVue(options) {  this._init(options);}myVue.prototype._init = function (options) {    this.$data = options.data; // this.$data = {number: 0}  }复制代码

然后我们应该对data进行处理,重写data的set和get函数。我们定义一个defineReactive函数,利用Object.defineProperty 来实现对对象的响应式化,形参是一个 obj(需要绑定的对象)、key(obj的某一个属性),val(具体的值)。

function myVue(options) {  this._init(options);}myVue.prototype._init = function (options) {    this.$data = options.data; // this.$data = {number: 0}  }function defineReactive(obj,key,val){     Object.defineProperty(obj, key, {        enumerable: true, // 可枚举        configurable: true, // 可被删除        get: function reactiveGetter () {            return val;                 },        set: function reactiveSetter (newVal) {            console.log(`更新${newVal}`);            if (newVal === val) {                // 如果新的值与旧的值相等                return            };            val = newVal;        }    });}复制代码

接下来我们还得写一个_observer函数,来对data中的每一个属性来进行defineReactive处理。

function myVue(options) {    this._init(options);}myVue.prototype._init = function (options) {    console.log('_init执行')    this.$data = options.data; // this.$data = {number: 0}    // 修改_init函数    this._observer(this.$data)}myVue.prototype._observer = function (obj) {    console.log('_observer执行')        // 循环遍历data        for (value in obj) {            // 使用 hasOwnProperty 方法判断属性是否存在            if (obj.hasOwnProperty(value)) {                if (typeof obj[value] === 'object') { //如果值还是对象,则遍历处理                    this._observer(obj[value])                }                // 执行defineReactive对data属性进行处理                defineReactive(obj,value,obj[value])            }        }    }        function defineReactive(obj, key, val) {            console.log('对data进行重写')            Object.defineProperty(obj, key, {                enumerable: true, // 可枚举                configurable: true, // 可被删除                get: function reactiveGetter() {                    return val;                },                set: function reactiveSetter(newVal) {                    console.log(`触发视图更新!+${newVal}`);                    if (newVal === val) {                        // 如果新的值与旧的值相等                        return                    };                    val = newVal;                }            });        }复制代码

到这里我们的简单的响应式系统就做好啦。代码在,复制粘贴到chrome中就可以看到输出啦。

转载于:https://juejin.im/post/5cd1789b6fb9a0322c42a38c

你可能感兴趣的文章
http协议与http代理
查看>>
【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例...
查看>>
Redis+Spring缓存实例
查看>>
Storm集群安装详解
查看>>
centos7.x搭建svn server
查看>>
原码编译安装openssh6.7p1
查看>>
项目实战:自定义监控项--监控CPU信息
查看>>
easyui-datetimebox设置默认时分秒00:00:00
查看>>
蚂蚁分类信息系统5.8多城市UTF8开源优化版
查看>>
在django1.2+python2.7环境中使用send_mail发送邮件
查看>>
“Metro”,移动设备视觉语言的新新人类
查看>>
PHP源代码下载(本代码供初学者使用)
查看>>
Disruptor-NET和内存栅栏
查看>>
Windows平台ipod touch/iphone等共享笔记本无线上网设置大全
查看>>
播放加密DVD
查看>>
产品设计体会(3013)项目的“敏捷沟通”实践
查看>>
RHEL6.3基本网络配置(1)ifconfig命令
查看>>
网络诊断工具之—路由追踪tracert命令
查看>>
Java模拟HTTP的Get和Post请求(增强)
查看>>
php 环境搭建(windows php+apache)
查看>>