vue2.0/vue3.0响应式源码实践,麻麻,我再也不怕被面试官提问啦

  • 写在前面
  • vue2.0响应式源码实现
    • 1. 先创建一个对象
    • 2.实现observer方法
    • 3.接下来我们对observer函数进行改造
    • 4. 假如给data添加不存在key会如何呢?
    • 5. 假如data里面的数据是多层嵌套对象呢?
    • 6. 假如data里面的数据是多层嵌套数组呢?
  • vue3.0使用小测


写在前面

震惊!!! 2019年10月5日,尤小右公开了 Vue 3.0 的源代码。源码地址:vue-next,此次更新的主要内容除了自行查看源码还可以在知乎上进行了解尤小右 3.0 RFC,在这两篇的基础上,接下来我将为大家展示最近学习到3.0的内容解读

了解3.0的进步,我们得先了解2.0的响应式原理,如果已经知道其优势劣势的大佬自行跳过~~

vue2.0响应式源码实现

看过官方文档的同学都知道Vue 响应式系统的解释: 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为getter/setterObject.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因

下面我们将大概先实现vue2.0响应

原理:使用 Object.defineProperty 可以重新定义属性,并且给属性增加 getter 和setter;

1. 先创建一个对象

// 我们先创建一个对象,然后通过某个方法去监听这个对象,当对象的值改变时,触发操作
let defalutName = ''
let data = {name:''}
// observer监听函数
observer(data)
console.log(data.name);
// expected output: Magic Eno// 给data里面的name赋值 = "Eno"
data.name = 'Eno'
console.log(data.name);   // expected output: Enoconsole.log(defalutName); // expected output: Eno

2.实现observer方法

observer的效果要求很简单,就是监听data对象,当data里面的属性值改变时,监听到其改变;
下面实现一个简陋的双向数据绑定,即data的name改变时,defaultName也要改变,实现双向数据绑定,即defalutName与data对象的name双向绑定了

let defalutName = ''
let data = {name:''};function observer (data) {//Object.defineProperty直接在对象上定义新属性,或修改对象上的现有属性,然后返回对象。
//不了解的请转MDN文档 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/definePropertyObject.defineProperty(data, 'name', {get(){return defalutName},set(newValue){defalutName = newValue}});
}
//
observer(data)
console.log(data.name);
// expected output: ''// 给data里面的name赋值 = "Eno"
data.name = 'Eno'
console.log(data.name);   // expected output: Enoconsole.log(defalutName); // expected output: Eno

3.接下来我们对observer函数进行改造

上面我们的observer对象并没有对data的所有值进行监听,接下来我们完善oberver函数如下:


function observer(data){// 判断是否为对象 如果不是则直接返回,Object.defineProperty是对象上的属性if(typeof data !== 'object' || data == null){return data;}for(let key in data){defineReactive(data,key,data[key]);}
}
function defineReactive(data,key,value){//Object.defineProperty直接在对象上定义新属性,或修改对象上的现有属性,然后返回对象。//不了解的请转MDN文档 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/definePropertyObject.defineProperty(data, key, {get(){console.log('获取了值') // 在此做依赖收集的操作return value },set(newValue){if(newValue !== value){console.log('设置了值')value = newValue}}});
}let data = {name:'',age:18};
observer(data)// 给data里面的name赋值 = "Eno"
data.name = 'Eno'
console.log(data.name);
// 设置了值
// 获取了值
// Enodata.age = 12console.log(data.age);
// 设置了值
// 获取了值
// 12
  • 输入如图

    此时更新data里面的所有值都触发了defineProperty 的get和set方法

补充:什么是依赖收集? 我们都知道,当一个可观测对象的属性被读写时,会触发它的getter/setter方法。如果我们可以在可观测对象的getter/setter里面,执行监听器里面的update()方法;不就能够让对象主动发出通知了吗?

4. 假如给data添加不存在key会如何呢?

// ...
let data = {name:'',age:18};
observer(data)// 给data里面的name赋值 = "Eno"
// data.name = 'Eno'
// console.log(data.name);
//  data.age = 12
//  console.log(data.age);
data.gender = '男'

输出结果如下:

由图可知,并没有触发set和get,这个因为,在我们对data进行监测的时候是没有gender这个属性值的,因此我们如果想要对新增的属性进行监听的话,需要在赋值后再进行一次监听,即vm.$set的效果;我们可以创建一个reactiveSet函数如下:

function reactiveSet (data,key,value) {data[key] = valueobserver(data)
}let data = {name:'',age:18};
observer(data)// 给data里面的name赋值 = "Eno"
// data.name = 'Eno'
// console.log(data.name);
//  data.age = 12
//  console.log(data.age);
// 通过reactiveSet添加属性
reactiveSet(data,'gender','男')
console.log(data.gender)

执行结果如下:

此时是可以响应的,不过vue并不是这样做的,下面可以看vue的源码
vuejs in github
里面是这样判断的,如果这个key目前没有存在于对象中,那么会进行赋值并监听。但是这里省略了ob的判断;

补充: ob是什么呢? vue初始化的数据(如data中的数据)在页面初始化的时候都会被监听,而被监听的属性都会被绑定__ob__属性,下图就是判断这个数据有没有被监听的。如果这个数据没有被监听,那么就默认你不想监听这个数据,所以直接赋值并返回

5. 假如data里面的数据是多层嵌套对象呢?

目前,我们是对data一个简单对象进行监听,思考

vue 2.0响应式源码实践,麻麻,我再也不怕被面试官提问啦相关推荐

  1. vue3.0响应式源码实践,vue3.0初体验

    vue3.0响应式源码实践,vue3.0初体验 镇楼图--杀生丸.jpg vue-next(vue3.0预体验) 1. 使用: 2.vue-next的目录结构 3. reactive内部实现 作者上篇 ...

  2. 【Vue3源码学习】响应式源码解析:reactive、effect、ref

    源码版本 Vue3.2.24 废话不多说,直接开始!!! reactive响应式 源码地址:packages/reactivity/reactive.ts 先看一下在 Vue3 中定义的几个用来标记目 ...

  3. 【Vue 3.0 新特性(四)】Vue 3.0 响应式系统原理

    文章前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:内容较多,建议通过左侧导航栏进行阅读 Vue 3.0 响应式系统原理 基础回顾 Vue.js 响应式回顾 Proxy 对象实现属性监听 多层属 ...

  4. php个人博客响应式源码下载,Thinkphp5.0大气响应式青春博客个人博客源码

    Thinkphp5.0大气响应式青春博客个人博客源码 青春博客功能模块 1.删减说说和相册 主要功能减少不需要的功能,之前的功能都是参考别人的功能去使用,在博客使用的2年期间,发现说说和相册的功能基本 ...

  5. vue --- 2.0响应式补充

    补充: 数组的响应式 // 对数组的方法进行重写 // 1. 不能影响本来的方法 // 2. 调用的时候可以找到它 let odlArrayPrototype = Array.prototype; l ...

  6. 帝国CMS资讯自适应HTML5响应式源码,简单而不简约自适应HTML5响应式文章新闻帝国CMS网站模板整站手机...

    版本更新 模板已经适配到最新帝国CMS7.5(部分早期源码模板没有适配到最新)!截止2019-持续追踪更新针对机房黑产利用,和帝国CMS一个XS漏洞利用方法的堵截!正式版已补,请已运营的小伙伴找我查看 ...

  7. PHP客户关系项目,【php源码】最新企业客户关系管理系统CRM源码|Thinkphp开发企业客户关系管理系统响应式源码 线索发掘、商机转化、客户挖掘、客户关怀、报表统计等...

    源码介绍: 悟空CRM主要面向于中小型企业,帮助中小型企业降低工作强度,提升工作效率,并有效提升项目成功率,提高企业效益. 悟空CRM能全面跟踪业务员的项目跟进流程,从线索录入.商机转换.成为客户,到 ...

  8. 面试官系统精讲Java源码及大厂真题 - 40 打动面试官:线程池流程编排中的运用实战

    40 打动面试官:线程池流程编排中的运用实战 没有智慧的头脑,就像没有蜡烛的灯笼. --托尔斯泰 引导语 在线程池的面试中,面试官除了喜欢问 ThreadPoolExecutor 的底层源码外,还喜欢 ...

  9. 面试官系统精讲Java源码及大厂真题 - 26 惊叹面试官:由浅入深手写队列

    26 惊叹面试官:由浅入深手写队列 人生的价值,并不是用时间,而是用深度去衡量的. 引导语 现在不少大厂面试的时候会要求手写代码,我曾经看过一个大厂面试时,要求在线写代码,题目就是:在不使用 Java ...

最新文章

  1. 两下或多下回车造成数据库多次提交事物的解决方法
  2. java 抽象类继承抽象类_Java之继承、抽象类、接口篇
  3. 计算机视觉论文-2021-07-01
  4. 如何搭建一个spring boot项目
  5. 前向算法(Forward Algorithm)
  6. Java程序---学生管理系统的登录和注册
  7. 随机过程之更新理论的应用
  8. java 自定义列表_自定义列表标签
  9. JavaScript “use strict“(严格模式)
  10. SpringBoot+Vue下载文件Excel、PDF下载后打不开
  11. Android Studio系统状态栏,设置setSmallIcon通知图标无效问题及解决方案
  12. [转]ArcGIS计算图斑的四邻坐标(XMin,XMax,YMin,YMax)
  13. win10计算机日历不能用,手把手操作win10电脑日历打不开的详尽处理措施
  14. Nachos 3.4入门的两个问题
  15. 高校青年教师现状引关注(转载)
  16. 广告有哪些方式,可以降低用户反感?
  17. 预测交通拥堵,TranSEC助力城市交通“智”变
  18. 毕达哥拉斯的面包规矩
  19. 雅思作文模板.html,2015雅思小作文模板「万能」
  20. php 签名 bom,PHP与Unicode签名(BOM,Byte Order Mark)

热门文章

  1. 推荐系统评价:什么是好的推荐系统?
  2. 100首好听的英文歌
  3. Android APP开机启动,安卓APP开发自启动,安卓启动后APP自动启动 Android让程序开机自动运行APP
  4. Ubuntu系统上轻松截图的几种方法介绍
  5. 深度学习部署神器——triton inference server入门教程指北
  6. 处理LetsEncrypt证书签发错误acme-v02.api.letsencrypt.org timeout
  7. 区间最值问题: Balanced Lineup G
  8. Unity游戏优化指南大全(持续更新中!)
  9. python抢拼多多_python:拼多多订单接口api
  10. 如何用PDCA循环提高现场管理?