关注「松宝写代码」,精选好文,每日一题

​时间永远是自己的

每分每秒也都是为自己的将来铺垫和增值

作者:saucxs | songEagle

来源:原创

一、前言

文章首发在「松宝写代码」

2020.12.23 日刚立的 flag,每日一题,题目类型不限制,可以是:算法题,面试题,阐述题等等。

本文是「每日一题」第 5 题:「每日一题」到底该如何回答:vue数据绑定的实现原理?

往期「每日一题」:

二、vue数据绑定的实现原理?

这个题目本身不是特别难,只能说是作为社招的基础面试题,但是如果想回答好这道题也不是很容易。

不信接着往下看

1、概括回答

vue.js是一个非常优秀的前端开发框架,使用vue的版本是v2.x

vue几个核心的地方:vue实例化,虚拟DOM,模板编译过程,数据绑定。

我们开始回到正题,vue.js的作者尤雨溪最初就是尝试实现一个类似angular1的东西,发现里面对于数据处理非常不优雅,于是创造性的尝试利用ES5中的Object.defineProperty来实现数据绑定,于是就有了最初的vue。

vue的数据绑定的实现原理离不开vue中响应式的数据处理方式。

我们可以回想一下官网的图:

vue的响应式基本原理:

  • 1、vue会遍历此data中对象所有的属性,

  • 2、并使用Object.defineProperty把这些属性全部转为getter/setter,

  • 3、而每个组件实例都有watcher对象,

  • 4、它会在组件渲染的过程中把属性记录为依赖,

  • 5、之后当依赖项的 setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。

2、亮点回答

概括回答我们只回答了使用ES5的方法 Object.defineProperty 实现数据的监听的,那么具体是如何实现还是没有讲的很清楚。

这时候我们需要问自己,如何找亮点?

vue的响应式原理设计三个重要对象:Observer,Watcher,Dep。

  • Observer对象:vue中的数据对象在初始化过程中转换为Observer对象。

  • Watcher对象:将模板和Observer对象结合在一起生成Watcher实例,Watcher是订阅者中的订阅者。

  • Dep对象:Watcher对象和Observer对象之间纽带,每一个Observer都有一个Dep实例,用来存储订阅者Watcher。

当属性变化会执行主题对象Observer的dep.notify方法, 这个方法会遍历订阅者Watcher列表向其发送消息, Watcher会执行run方法去更新视图。

依赖关系图如下,更能方面我们的理解

接着我们需要补充的是:模板编译过程中的指令和数据绑定都会生成Watcher实例,实例中的watch属性也会生成Watcher实例。

说的这些有没有觉得有点乱,那我们总结一下如何亮点回答

  • 1、在生命周期的initState方法中将data,prop,method,computed,watch中的数据劫持, 通过observe方法与Object.defineProperty方法将相关对象转为换Observer对象。
  • 2、然后在initRender方法中解析模板,通过Watcher对象,Dep对象与观察者模式将模板中的 指令与对象的数据建立依赖关系,使用全局对象Dep.target实现依赖收集。
  • 3、当数据变化时,setter被调用,触发Object.defineProperty方法中的dep.notify方法, 遍历该数据依赖列表,执行器update方法通知Watcher进行视图更新。
  • vue是无法检测到对象属性的添加和删除,但是可以使用全局Vue.set方法(或vm.$set实例方法)。
  • vue无法检测利用索引设置数组,但是可以使用全局Vue.set方法(或vm.$set实例方法)。
  • 无法检测直接修改数组长度,但是可以使用splice

然后写一个使用Object.defineProperty实现监听变量

var obj = {};
var a;
Object.defineProperty(obj, 'a', {
get: function() {
console.log('get val'); 
return a;
},
set: function(newVal) {
console.log('set val:' + newVal);
a = newVal;
}
});
obj.a; // get val
obj.a = 'saucxs' //set val

如果上面代码格式出现问题,可以查看下面代码图片

3、进阶回答

因为现在vue已经到3了,不再是停留在2的时候,这个时候,可以把3的原理简单说一下。

这个时候不应该是ES6的proxy特性上场了,proxy是ES6的新增的功能,可以用来定义对象中的操作。

let p = new Proxy(target, handler);
// `target` 代表需要添加代理的对象
// `handler` 用来自定义对象中的操作

如果上面代码格式出现问题,可以查看下面代码图片

可以很方便的使用 Proxy 来实现一个数据绑定和监听.

let onWatch = (obj, setBind, getLogger) => {
let handler = {
get(target, property, receiver) {
getLogger(target, property)
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
setBind(value);
return Reflect.set(target, property, value);
}
};
return new Proxy(obj, handler);
}; let obj = { saucxs: 1 }
let value
let p = onWatch(obj, (v) => {
value = v
}, (target, property) => {
console.log(`Get '${property}' = ${target[property]}`);
})
p.saucxs = songEagle // bind `value` to `songEagle`
p.saucxs // -> Get 'saucxs' = songEagle

如果上面代码格式出现问题,可以查看下面代码图片

然后在对比vue2和vue3的区别是什么?

以及为啥在数据监听上做了升级?

vue为什么对数组对象的深层监听无法实现,因为组件每次渲染都是将data里的数据通过defineProperty进行响应式或者双向绑定上,之前没有后加的属性是不会被绑定上,也就不会触发更新渲染。

区别:

1、语法层面上

  • defineProperty只能响应首次渲染时候的属性,
  • Proxy需要的是整体监听,不需要关心里面有什么属性,而且Proxy的配置项有13种,可以做更细致的事情,这是之前的defineProperty无法达到的。

2、兼容层面上

  • vue2.x之所以只能兼容到IE8就是因为defineProperty无法兼容IE8,其他浏览器也会存在轻微兼容问题。
  • proxy的话除了IE,其他浏览器都兼容,这次vue3还是使用了它,说明vue3直接放弃了IE的兼容考虑。

各种福利

文章首发在「松宝写代码。「松宝写代码」:开发知识体系构建,技术分享,项目实战,实验室,每日一题,带你一起学习新技术,总结学习过程,让你进阶到高级资深工程师,学习项目管理,思考职业发展,生活感悟,充实中成长起来。问题或建议,请公众号留言。

1、字节内推福利

回复「校招」获取内推码

回复「社招」获取内推

回复「实习生」获取内推

后续会有更多福利

2、学习资料福利

回复「算法」获取算法学习资料

3、每日一题

「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?的更多相关文章

  1. 「每日一题」面试官问你对Promise的理解?可能是需要你能手动实现各个特性

    关注「松宝写代码」,精选好文,每日一题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目类 ...

  2. LOJ6003 - 「网络流 24 题」魔术球

    原题链接 Description 假设有根柱子,现要按下述规则在这根柱子中依次放入编号为的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法 ...

  3. LOJ6002 - 「网络流 24 题」最小路径覆盖

    原题链接 Description 求一个DAG的最小路径覆盖,并输出一种方案. Solution 模板题啦~ Code //「网络流 24 题」最小路径覆盖 #include <cstdio&g ...

  4. LOJ6001 - 「网络流 24 题」太空飞行计划

    原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...

  5. LOJ6000 - 「网络流 24 题」搭配飞行员

    原题链接 题意简述 求二分图的最大匹配. 题解 这里写的是匈牙利算法. 表示节点的当前匹配. 为真表示在这一轮匹配中,无法给节点一个新的匹配.所以如果为真就不用再dfs它了,直接continue就好. ...

  6. LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集

    #6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   ...

  7. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  8. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  9. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

随机推荐

  1. springmvc跨域问题

    1.跨域问题: 按照网上所有的方法试了一遍,都没跨过去,正在无助之际,使用filter按照下面的方法解决的时候出现了转机: 添加filter: package com.thc.bpm.filter; ...

  2. moviepy音视频剪辑:视频剪辑基类VideoClip详解

    ☞ ░ 前往老猿Python博文目录 ░ 一.概述 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>和<moviepy音视频剪辑:moviepy中的剪辑基类Cl ...

  3. 转:Cookie详解

    没怎么坐过客户端相关的工作,所以写爬虫的时候,很多概念都很模糊,学习起来很困难.现在想攻坚一下,所以找了一下cookies相关的内容. HTTP cookies,通常又称作"cookies& ...

  4. 第9.9节 Python文件随机读写定位操作方法seek

    类似于C语言,Python也提供了文件位置定位的操作方法seek. 一. 语法 seek(offset, whence=SEEK_SET) 语法释义: 1)offset :将文件当前操作位置移动偏移量 ...

  5. 第十章、Qt Designer中的Spacers部件

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一. 引言 在Designer的部件栏中,有两种类型的Spacers部件,下图中上面布局中为一个水平 ...

  6. 【系统设计】WMS系统中 库存、盘点、移库、拆库功能的设计(库内管理)

    最近负责WMS系统 盘点 移库 两个功能模块的功能及数据库设计. 物流仓储系统的搭建,要基于仓库的实际情况,整理内部员工需求,再参考其他WMS系统,经过长时间的讨论和研究,最终转化为产品需求. 这里先 ...

  7. python 读取excel表格内不同类型的数据

    不同类型数据对应值: #coding=utf-8 import os import xlrd from datetime import datetime,date newparh = os.chdir ...

  8. 小程序editor篇-基本使用图片上传

    今天小程序项目内,要弄一个editor,富文本编辑功能,支持图文并茂,前几天刚好看了小程序的demo应用,刚好看到editor这个东东,那就安排! 官网示例git地址 大概看了下文档,拉下官方示例,看 ...

  9. go学习的第7天

    不容易啊,坚持7天了呢,今天开始看视频学习 https://www.bilibili.com/video/BV1pt41127FZ?from=search&seid=4441824587572 ...

  10. Scrum冲刺_Day03

    一.团队展示: 1.项目:light_note备忘录 2.队名:删库跑路队 3.团队成员 队员(不分先后) 项目角色 黄敦鸿 后端工程师.测试 黄华 后端工程师.测试 黄骏鹏 后端工程师.测试 黄源钦 ...