What is the difference between Vue2 and Vue3 in responsiveness? The following article will introduce to you the difference between Vue2 and Vue3 responsiveness. I hope it will be helpful to you!
For the first time, you must first understand the principle and process of responsiveness before you can proceed further: from shallow to deep is the way to go. (Learning video sharing: vuejs video tutorial)
This kind of picture clearly describes the responsive principle: each The component will generate a render function
(rendering function), and the render function will generate a vnode (virtual DOM)
, which will trigger data## when the render function is executed. #Inside
getter, dependency is generated when triggered (which data variable is triggered by data, which variable will be observed). Later, you need to check whether this variable is observed due to previous dependencies. If so
setter will be triggered to modify the data. If not, the monitoring operation will be performed directly. If it is determined that it was re-observed as a dependency before, then perform the
re-render re-render operation and perform the
pacth operation. Using responsive principles can achieve better data rendering.
data hijacking through Object.defineProperty, allowing data to be updated responsively.
Object.defineProperty()The method will directly define a new property on an object, or modify an existing property of an object, and return this object.
Object.defineProperty(obj, prop, descriptor)
##obj: The object to define properties.Object type
Fetch and modify to intercept
(data hijacking).
(change method of array) by overriding a series of methods that update the array
packaged). <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">let person = { // 模拟Vue2实现响应式
name:&#39;亮哥&#39;,
age:18
}
Object.defineProperty(person, "age", {
// 当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除,解决新增/删除属性,数据无响应问题
configurable: true,
get: () => {
// 收集依赖代码...
return person.age;
},
set: (newVal) => { // 一个给属性提供 setter 的方法
// 当属性值发生变化时我们可以进行额外操作 如调用监听器
person.age = newVal;
// 通知更新视图代码...
},
});
data.age = 25 // 触发set方法</pre><div class="contentsignin">Copy after login</div></div>
Recursively traverse the data object attributes, which consumes a lot of moneyThrough Proxy (proxy): intercept changes in any properties in the object, including: Reading and writing of attribute values, adding attributes, deleting attributes, etc. Through Reflect (reflection): Operate on the properties of the source object.
Proxy
let data = { // 模拟Vue2实现响应式 name:'强哥', age:20 } const proxy = new Proxy(data, { // 拦截读取属性值 get (target, prop) { return Reflect.get(target, prop) }, // 拦截设置属性值或添加新属性 set (target, prop, value) { return Reflect.set(target, prop, value) }, // 拦截删除属性 deleteProperty (target, prop) { return Reflect.deleteProperty(target, prop) } }) proxy.name = 'tom'
) behaviors of attributes. As a constructor,
Proxy
accepts two parameters: <ul><li>第一个参数是所要代理的目标对象(上例是一个<code>data
对象),即如果没有Proxy
的介入,操作原来要访问的就是这个data
对象。这里的对象是指对象类型(数组也是对象类型)。
handler
,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作。比如,上面代码中,配置对象有一个get
方法,用来拦截对目标对象属性的访问请求。get
方法的两个参数分别是目标对象和所要访问的属性。注意: 要使Proxy起作用,必须针对Proxy实例(上例是dataProxy对象)进行操作,而不是针对目标对象(上例是data对象)进行操作。
可以看出Proxy
不仅可以实现Object.defineProperties
的功能,还有其他的操作也可以拦截。
说完Proxy
就必须要说一说Reflect
这个ES6新增的API。Reflect
对象和Proxy
对象一样也是用来操作对象的,但是Reflect
对象的设计目的有重大的意义。
Reflect
是一个内置的对象,它提供拦截 JavaScript 操作的方法。Reflect不是一个函数对象,因此它是不可构造的。Reflect
的所有的方法都是静态的就和Math
一样,目前它还没有静态属性。
Reflect的常见方法
我们可以将之前Proxy案例中对原对象的操作都修改为Reflect来操作
const objProxy = new Proxy(obj,{ has:function(target,key){ return Reflect.has(target,key) } set:function(target,key,value){ return Reflect.set(target,key,value) } get:function(target,key){ return Reflect.get(target,key) } deleteProperty:function(target,key){ return Reflect.deleteProperty(target,key) } })
function reactive(target = {}) { if (typeof target !== "object" || target == null) { return target } // 代理配置 const proxyConf = { get(target, key, receiver) { //只监听对象本身(非原型)属性 const ownKeys = Reflect.ownKeys(target) if (ownKeys.includes(key)) { //如果是本身的属性就监听,如果是对象原型的属性就不监听 console.log("get", key) } const result = Reflect.get(target, key, receiver) //(惰性)深度监听-->提升性能 return reactive(result) }, set(target, key, val, receiver) { // 重复的数据不处理 if (val === target[key]) { return true } // 监听是否是新增的key const ownKeys = Reflect.ownKeys(target) if (ownKeys.includes(key)) { console.log("已有的key", key) } else { console.log("新增的key", key) } const result = Reflect.set(target, key, val, receiver) console.log("set", key, val) return result //通过return的值可以看出是否设置成功 }, deleteProperty(target, key) { const result = Reflect.deleteProperty(target, key) console.log("delete property", key) return result //是否删除成功 }, } // 生成代理对象 const observed = new Proxy(target, proxyConf) return observed }
Vue3的响应式逻辑如何一步一步构造出来的,我放在另一篇博文Vue3响应式实现逻辑:
https://juejin.im/post/6854573217038893070
【相关视频教程推荐:web前端】
The above is the detailed content of What is the difference between Vue2 and Vue3 in terms of responsiveness? Simple comparison. For more information, please follow other related articles on the PHP Chinese website!