直接开讲:

​ 由于这个Vue底层封装的函数太多了,我这里只讲思路不说具体的执行了什么函数.

​ const vm=new Vue({这里写一个data,可以是对象也可以是函数}) 在写这段代码的时候new就已经开始运转了

​ 首先:Vue底层是一个构造函数,然后底层在这个构造函数的原型(prototype)上放了一个_init方法,我们在new的时候,就启动这个方法了,可以知道这个方法的this就是构造函数的实例对象的__proto__,在_init这个方法里面就把this赋值给了一个变量叫做vm,然后往这个vm上面放了一个$options,再把{}赋值给了$options.

​ 其次,延续上面,又调用了一个函数,把vm传过去,在函数里面判断vm.$options.data是否为function,如果是function就涉及到了一个this指向问题,就需要把这个函数的this指向vm,如果是对象那么直接进入下面,下面就是在vm身上添加了一个_data属性,这个再给这个_data赋与vm.$options.data,然后直接将vm.$options.data传入到另外一个函数中,这个函数在这里取个名字叫observe(),到后面会循环使用这个函数,也可以说是一个递归函数;

​ 延续上一段,在另外一个函数中判断传送过来的如果不是一个对象或者说是不是null,满足这其中任意一个条件就return;如果是对象就直接return new Observer(vm.$options.data).

​ (下面这一段先说一下代理vm.$options.data,调用set方法往里面添加对象和数组的情况,也没有重写数组的7个方法)

​ 这里这个new Observer(data)是vue源码中写的一个类,这个类里面会判断data是不是一个数组,是数组就将这个数组里面的所有元素都遍历一遍,然后在传递到observe(item)对象里面,如果一直嵌套就一直回去这个函数,这里需要说一下,如果是数组里面对应索引处是一个普通数据类型就会在observe函数里return掉.这就表示在vue2中数组中的普通数据类型是不会进行数据代理的

​ 上面的这一段说了是数组的情况,这里说一下是对象的情况,如果传入observe(data)是一个对象,那么直接Object.keys().forEach(item=>{在这里调用一个函数,将目标函数和需要代理的key传送过去}),传送过去就会进行一个判断,如果是对象就继续将这个对象传入到observe(item)里面去,直到他不是一个对象为止.

​ 注:如果使用数组的方法去添加值,只用上面的这些逻辑是不够的,刚添加上的数据不会被检测到.那么如果想解决这个问题,就需要在使用push方法时候吧push进去的东西进行一次数据代理.

​ vue对数组方法的重写:①将Array的prototype赋值给一个对象②使用Object.create()方法将创建的这个对象的this指向①中的对象,现在从当前这个对象往上推,其实就有三层原型了.(Array.prototype.proto.proto)然后把这个原型给了data.proto,这里要注意,现在data有了三层原型(data.proto.proto.proto)然后data.proto.__proto__这个对象里面有所有的数组的方法,然后vue给data.__proto__上面有加了7个方法('push','pop','shift','unshift','reserve','sort','splice'),然后调用push,肯定是data调的,然后data的原型第一层就能够拿到重写好的push(),还给push进去的数据进行了代理.

总结:

​ 底层给data中的数据进行了数据代理,不会代理数组中存在的基本数据类型元素,对set方法添加的数据进行判断并代理,给数组方法进行重写并代理数组中存在的对象里面的属性.重写后的数组添加新元素会进行判断并代理

Vue源码中的数据代理的更多相关文章

  1. Vue源码学习之数据初始化

    首发地址:CJWbiu's Blog 在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props.methods.data等.而在methods的方 ...

  2. 【Vue】VUE源码中的一些工具函数

    Vue源码-工具方法 /* */ //Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性. var emptyObject = Object.freeze({}); // th ...

  3. vue源码中computed和watch的解读

    computed 会基于其内部的 响应式依赖 进行缓存. 只在相关 响应式依赖发生改变 时 它们才会重新求值. 可以在将模板中使用的常量放在计算属性中. watch 监听数据变化,并在监听回调函数中返 ...

  4. nodeType属性在vue源码中的使用

    每个节点都有一个 nodeType 属性,用于表明节点的类型,节点类型由 Node 类型中定义12个常量表示:  nodeType在vue中的应用 在vue编译的过程中需要查找html结构中的双大括号 ...

  5. 了解一下vue源码中vue 的由来

     我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/entry-r ...

  6. Vue源码中compiler部分逻辑梳理(内有彩蛋)

    目录 一. 简述 二. 编译流程 三. 彩蛋环节 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 ...

  7. 从Vue源码中我学到了几点精妙方法

    话不多说,赶快试试这几个精妙方法吧!在工作中肯定会用得到. 立即执行函数 页面加载完成后只执行一次的设置函数. (function (a, b) { console.log(a, b); // 1,2 ...

  8. Vue源码解析---数据的双向绑定

    本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...

  9. 【Vuejs】350- 学习 Vue 源码的必要知识储备

    前言 我最近在写 Vue 进阶的内容.在这个过程中,有些人问我看 Vue 源码需要有哪些准备吗?所以也就有了这篇计划之外的文章. 当你想学习 Vue 源码的时候,需要有扎实的 JavaScript 基 ...

  10. vue源码解析之observe

    一. vue文档中有"由于 JavaScript 的限制,Vue 不能检测以下数组的变动",是否真是由于JavaScript的限制,还是出于其他原因考虑 当你利用索引直接设置一个数 ...

随机推荐

  1. 【Go并发编程】Goroutine的基本使用

    goroutine是什么 goroutine即协程,使用go关键字开启一个协程异步执行代码. 注意,main函数也是个goroutine. 基本使用 使用go执行子任务,会交替执行(和时间片一样). ...

  2. 修改ctags让fzf.vim插件显示C,C++方法声明的标签

    背景 在 vim 中使用 fzf.vim 插件可以进行方便的搜索文件, 源码TAG, GIT 记录等, 最近抽空看了下 BTags 命令在 c, c++ 文件中, 无法显示头文件中的函数声明 标签问题 ...

  3. Docker中Mysql容器忘记密码的处理方法

    今天非常的倒霉,因为学习了Vue的相关知识,想自己写一个后端服务器来练习一下Vue 然后 忘记了Docker中Mysql的密码... 很抽象 下面是我的解决方法 一.如果在本地的Navicat Pre ...

  4. Os-ByteSec

    Os-ByteSec 目录 Os-ByteSec 1 信息收集 1.1 端口扫描 1.2 后台目录扫描 2 服务漏洞利用 2.1 检测smb服务漏洞 2.2 GetShell 3 提权 3.1 尝试提 ...

  5. Vulhub 漏洞学习之:Couchdb

    Vulhub 漏洞学习之:Couchdb 目录 Vulhub 漏洞学习之:Couchdb 1 Couchdb 垂直权限绕过漏洞(CVE-2017-12635) 1.1 漏洞利用过程 2 Couchdb ...

  6. node.js 历史版本下载

    https://nodejs.org/zh-cn/download/releases/

  7. JavaScript之异步编程

    什么是异步 异步:Asynchronous,async是与同步synchronous,sync相对的概念. 传统单线程编程中,程序的运行是同步的,指程序运行在一个控制流之中运行.而异步的概念就是不保证 ...

  8. linux常用操作指令记录

    https://maker.pro/linux/tutorial/basic-linux-commands-for-beginners ## 打开终端 ## **Ctrl+Alt+T** ## ls ...

  9. Socket:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

    https://blog.csdn.net/weixin_45932157/article/details/113999801 最近服务器的Socket代理软件经常报这个错误:log:Error On ...

  10. KCL v0.4.5 发布 - 更好的编写便利性改进,稳定性,体验提升与多平台支持

    简介 KCL 团队很高兴地宣布 KCL v0.4.5 版本现在已经可用!本次发布主要为 KCL 语言编写便利性和稳定性提升,错误信息改进以及更多平台包括 windows 版本支持以及更多下载方式支持. ...