Vue2的数据响应式原理

1、什么是defineProperty?

defineProperty是设置对象属性,利用属性里的set和get实现了响应式双向绑定;

语法:Object.defineProperty(要设置的对象,要修改的对象的属性,属性描述)

属性描述:
1、configurable - 表示此属性能否被delete,默认false;
2、enumerable - 表示此属性能否被枚举,默认为false;
3、value - 设置此属性对应的值,默认为undefined;
4、writable - 设置value属性能否被修改值,为true时方可被改变,默认为false;
5、get - 给属性提供getter方法,默认为undefined,访问该属性时,该方法会被执行,默认参数为this对象;
6、set - 给属性提供setter方法,默认为undefined,属性值修改时,会执行该方法,唯一参数为新的值; 获取对象所拥有属性的方法:Object.getOwnPropertyDescriptor(对象,对象某一属性) var obj = {
a: 1,
b: 2
}
var value = obj.b;
Object.defineProperty(obj,'b',{
configurable: false,//不能被deleted
enumerable: false,//不能被删除
writable: true,//可以被修改值
value: '22',//设置b为22
set: function(newValue){
console.log('新的value为'+ newValue);
value = newValue;
},
get: function(){
console.log('你设置了value');
return value;
},
})
console.log(Object.getOwnPropertyDescriptor(obj,'a')); //{value: 1, writable: true, enumerable: true, configurable: true} 2、实现双向绑定:
function vue(){
this.$data = {a: 1};//设置data
this.el = document.getElementById('app'); //设置根节点
this.dom = '';//虚拟dom
} //往原型上绑定监听方法
vue.prototype.observe = function(obj){
var self = this;
var value;
for(var key in obj){
value = obj[key];
if(typeof value === 'object'){ //如果是对象 需要递归循环执行此方法
this.observe(value);
}else{
Object.defineProperty(this.$data,key,{
get: function(){
//依赖收集 这里略过 代替源码里的 depend
return value;
},
set: function(newVal){
value = newVal;
self.render();//触发更新 代替源码里的dep.notify
}
})
}
}
} vue.prototype.render = function(){
this.dom = '我是' + this.$data.a;
this.el.innerHTML = this.dom;
} 3、数组监听实现
vue数组的特性: push shift unshift
对象的监听是通过defineProperty,而数组是通过dependArray
Object.create(proto,propertiesObject) //方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__ var arrPro = Array.prototype;
var arrObj = Object.create(arrPro);
var arr = ['push','pop','shift'];
//装饰者模式
arr.forEach(function(method,index){
arrObj[method]=function(){
var ret = arrPro[method].apply(this,arguments);
dep.notify();
return ret;
}
})

Vue3的数据相应原理

 let p = new Proxy(target, handler);
target: 目标对象
handler: 是一个对象,其属性是当执行一个操作时定义代理的行为的函数。
handler中常用的对象方法如下:
receiver => 此Proxy对象本身,也就是this指向;
1. get(target, propKey, receiver)
2. set(target, propKey, value, receiver)
3. has(target, propKey)
4. construct(target, args)
5. apply(target, object, args) 写法如下:
let a = new Proxy({},{
get: function(target,key,receiver){
return Reflect.get(target[key]);
//return target[key];
},
set: function(target, key, value, receiver){
return Reflect.set(target,key,value);
//return target[key] = value;
}
}) Object.defineProperty 存在如下缺点:
1. 监听数组的方法不能触发Object.defineProperty方法中的set操作(如果要监听的到话,需要重新编写数组的方法)。
2. 必须遍历每个对象的每个属性,如果对象嵌套很深的话,需要使用递归调用。 Proxy相比defineProperty 区别:
1、参数不一样,defineProperty第二个参数需要指定操作对象的具体key值,而Proxy指定的是最外层对象,这样就省去了循环;
2、defineProperty操作的是对象本身,改变了对象本身,而Proxy是改变对象代理,返回新对象;
3、defineProperty必须在最外层定义一个全局变量value,通过get将其return出去,而Proxy将返回值放到了参数中,直接return target[key];

Diff算法和virtual dom

注:virtual dom是一个虚拟层,并不正式存在

diff算法是直接去比对元素,元素里包含props 和 children, 一直进行到根节点,template中所有的节点都会有个diff,挂载了所绑定的一系列属性,通过遍历循环监听到变化,在vue3中作者改变了这种方式,在发布会中讲到对比vue2速度提升了6倍,

vue2的虚拟dom,会遍历所有子节点,全部用diff算法比对一次,遍历速度由dom数量决定;

vue3中会找出变化的项,只更新改变项;

Vue响应式原理的实现-面试必问的更多相关文章

  1. 深度解析 Vue 响应式原理

    深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...

  2. vue响应式原理,去掉优化,只看核心

    Vue响应式原理 作为写业务的码农,几乎不必知道原理.但是当你去找工作的时候,可是需要造原子弹的,什么都得知道一些才行.所以找工作之前可以先复习下,只要是关于vue的,必定会问响应式原理. 核心: / ...

  3. Vue源码--解读vue响应式原理

    原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...

  4. 详解Vue响应式原理

    摘要: 搞懂Vue响应式原理! 作者:浪里行舟 原文:深入浅出Vue响应式原理 Fundebug经授权转载,版权归原作者所有. 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是 ...

  5. 深入Vue响应式原理

    深入Vue.js响应式原理 一.创建一个Vue应用 new Vue({ data() { return { name: 'yjh', }; }, router, store, render: h =& ...

  6. vue响应式原理解析

    # Vue响应式原理解析 首先定义了四个核心的js文件 - 1. observer.js 观察者函数,用来设置data的get和set函数,并且把watcher存放在dep中 - 2. watcher ...

  7. 浅析Vue响应式原理(三)

    Vue响应式原理之defineReactive defineReactive 不论如何,最终响应式数据都要通过defineReactive来实现,实际要借助ES5新增的Object.definePro ...

  8. 深入解析vue响应式原理

    摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...

  9. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

随机推荐

  1. Java的常用类 String

    String类: 代表字符串, java程序中的所有字符串字面值(如, "abc")都是此类的实例实现 String是一个final类,代表不可变的字符序列 字符串是常量是用双引号 ...

  2. sticky用法

    可以用于滚动到一定距离以后让他实现定位效果. 比如滚动到50px的时候让导航栏固定定位. 用法:给最外层的div设置绝对定位 然后要固定的div设置position:sticky; top:0: 这样 ...

  3. 《STL源码剖析》——第五、六:关联容器与算法

    第五章.关联容器  5.0.关联容器 标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和multimap(多键映射表).这些容器的底层 ...

  4. Ubuntu TTy字体

    目的:修改tty终端下的字体大小,中文显示,字体美观问题 Linux版本:xubuntu14.04 当切换到tty终端模式式,中文乱码,且字体太小,影响阅读.在网上搜了一些资料,将问题及解决方案记录如 ...

  5. java_第一年_JDBC(2)

    上篇说到,通过JDBC可实现java编程程序和mysql数据库进行连接并交互,而交互后所形成的结果集是通过ResultSet对象来操作的. 创建ResultSet对象: stmt = conn.cre ...

  6. 57-python基础-python3-集合-集合常用方法-添加元素-add()-update()

    添加元素-add()-update() 1-add() add()用于增加一个元素值,原值修改,无返回值. 2-update()用于添加一个可迭代的对象,原值修改,无返回值. 下面依次向集合添加可迭代 ...

  7. python学习第十八天计算机字符编码

    人类语言和计算机语言二进制怎么沟通,最开始字符编码为ascii码对照表 包括数据和字母,没有汉字,中国自己搞了一套自己的编码 gb2312编码后来发展GBK编码,日本,韩国都,甚至台湾也搞自己的编码, ...

  8. 阿里云ECS服务安装 nginx+php+MariaDB完整版

    安装 Nginx想在 CentOS 系统上安装 Nginx ,你得先去添加一个资源库,像这样: vim /etc/yum.repos.d/nginx.repo使用 vim 命令去打开 /etc/yum ...

  9. Jmeter JAVA请求入门

    一.Jmeter完成一个java请求实现方法 两种实现方式: 实现JavaSamplerClient接口 继承AbstractJavaSamplerClient抽象类 二.使用AbstractJava ...

  10. break和continue能否跳出函数

    int func() { printf("In func, before continue.\n"); // continue; break; printf("In fu ...