Vue 响应式原理


vue的响应式原理? 什么是响应式,“响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码。例如,视图渲染中使用了数据,数据改变后,视图也会自动更新。

Vue 的响应式原理是核心是通过 ES5 的保护对象的 Object.defindeProperty 中的访问器属性中的 get 和 set 方法,data 中声明的属性都被添加了访问器属性,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。

 

Object.defineProperty怎么用, 三个参数?,有什么作用啊?

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

Object.defineProperty(obj, prop, {})

obj:需要定义属性的对象

prop:需要定义的属性

{}:要定义或修改的属性描述符。

value: "18", // 设置默认值得

enumerable: true, //这一句控制属性可以枚举 enumerable 改为true 就可以参与遍历了 默认值false

writable: true, // 控制属性可以被修改 默认值false

configurable: true, // 控制属性可以被删除 默认值false

get // 当有人读取 prop 的时候 get函数就会调用,并且返回就是 sss 的值

set // 当有人修改 prop 的时候 set函数就会调用, 有个参数这个参数就是修改后的值

 

Object.defineProperty 能定义symbol类型吗?

在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定 义key为Symbol的属性的方法之一。

 

vue2和vue3的响应式原理都有什么区别呢?

vue2 用的是 Object.defindProperty 但是vue3用的是Proxy

Object.defindProperty虽然能够实现双向绑定了,但是还是有缺点,只能对对象的属性进行数据劫持,所以会深度遍历整个对象,不管层级有多深,只要数组中嵌套有对象,就能监听到对象的数据变化无法监听到数组的变化,Proxy就没有这个问题,可以监听整个对象的数据变化,所以用vue3.0会用Proxy代替definedProperty。

上面就是一个典型的例子,当我们点击按钮想要根据数组 arr 的下标改变其元素的时候,你会发现 data 中的数据改变了,但是页面中的数据并没有改变。

我会用 this.$set( target, key, value ) 来解决

参数:

{Object | Array} target

{string | number} propertyName/index

{any} value

第一参数时指定要修改的数据 (target)

第二个参数就是你要设置数据的下标或者是属性名

第三个参数就是现在要修改的数据 (重新赋的值)

改变/添加 对象属性的时候:this.$set(data 实例,"属性名(添加的属性名)","属性值(添加的属性值)")

改变/添加 数组属性的时候:this.$set(data 实例,数组下标,"改变后的元素(添加的元素)")

原因 : vue在创建实例的时候把data深度遍历所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。让 Vue 追踪依赖,在属性被访问和修改时通知变化。所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

为什么要用 this.$set 呢?this.$set是干什么的?

当你发现你给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this.$set()这个方法了,简单来说this.$set的功能就是解决这个问题的啦。官方解释:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi'),你会发现vue官网是vue.set,vue.set的用法

那 Vue.set 和 this.$set 有什么区别 ?

Vue.set( ) 是将 set 函数绑定在 Vue 构造函数上,this.$set() 是将 set 函数绑定在 Vue原型上。

 

相关