Dieser Artikel vermittelt Ihnen das relevante Wissen über die datenbasierte Analyse und manuelle Implementierung der Daten. Wenn die Daten aktualisiert werden, wird die Ansicht automatisch aktualisiert, um die Änderungen in den Daten zu verfolgen wird Ihnen hilfreich sein.
var obj = {}var age Object.defineProperty(obj, 'age', { get: function() { consoel.log('get age ...') return age }, set: function(val) { console.log('set age ...') age = val }})obj.age =100 //set age ...console.log(obj.age)//get age ...
function defineReactive(data) { if (!data || Object.prototype.toString.call(data) !== '[object Object]') return; for (let key in data) { let val = data[key]; Object.defineProperty(data, key, { enumerable: true, //可枚举 configurable: true, //可配置 get: function() { track(data, key); return val; }, set: function() { trigger(val, key); }, }); if (typeof val === "object") { defineReactive(val); } }}function trigger(val, key) { console.log("sue set", val, key);}function track(val, key) { console.log("sue set", val, key);}const data = { name:'better', firends:['1','2']}defineReactive(data)console.log(data.name)console.log(data.firends[1])console.log(data.firends[0])console.log(Object.prototype.toString.call(data))
Diese Funktion defineReactve
wird verwendet, um Object.defineProperty
aus dem Funktionsnamen zu kapseln Es ist ersichtlich, dass die Funktion darin besteht, reaktionsfähige Daten zu definieren. Nach der Kapselung müssen nur Daten, Schlüssel und Wert übergeben werden.
Immer wenn der Schlüssel aus den Daten gelesen wird, wird die Track-Funktion ausgelöst und die Daten werden festgelegt zum Schlüssel der Daten, in der Set-Funktion Die Triggerfunktion löst die
Reaktionsfähigkeit des Arrays
Wir verwenden die Methode auf dem Array-Prototyp, um den Inhalt des Arrays zu ändern, wodurch der Getter und Setter nicht ausgelöst wirddefineReactve
用来对Object.defineProperty
进行封装,从函数名可以看出,起作用就是定义一个响应式数据,封装后只需要传递data,key和val就行
每当从data中读取key的时候触发track函数,往data的key中设置数据时,set函数中的trigger函数触发
我们通过Array原型上的方法来改变数组的内容不会触发getter和setter
整理发现Array原型中可以改变数组自身内容
的方法有7个,分别push
pop
shift
unshift
splice
sort
reverse
vue2 改写了这这7种方法
实现方式:
以Array.propertype为原型创建一个arrayMethods对象,再使用Object.setPropertypeOf(o, arryMethods)
将o的__proto__指向arrayMethods
使用
<template><p>{{name}}</p></template>
该模板中使用数据 name
, 我们要观察数据, 当数据的属性发生变化的时候, 可以通知哪些使用的地方,
这就是我们要先收集依赖,即把用到数据name的地方收集起来,然后等数据变化的时候,把之前收集好的依赖循环触发一遍,总结来说就是getter中收集依赖,在setter中触发依赖
Proxy对象用于创建一个对象的代理, 从而实现基本操作的拦截和定义(如属性查找、赋值、枚举、函数掉用等)
const p = new Proxy(target, handler)
target
要使用 Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p
的行为。
reflect是一个内置对象, 他提供拦截javascript操作的方法, 这些方法和Proxy handlers相同
Reflect.set将值分配给属性的函数。返回一个Boolean 如果更新成功则返回true
Reflect.get获取对象身上某个属性的值,类似target[name]
如何实现劫持
const dinner = { meal:'111'}const handler = { get(target, prop) { console.log('get...', prop) return Reflect.get(...arguments) }, set(target, key, value) { console.log('get...', prop) console.log('set',key,value) return Reflect.set(...arguments) }}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)console.log(proxy.meal)
代码中dinner 对象代理到handler上
跟defineProperty
区别defineProperty
. Nach dem Organisieren und Entdecken der Methoden im Array-Prototyp, die den Inhalt des Arrays selbst ändern
können, gibt es jeweils 7 push
pop
shift
unshift
splice
sort <code>reverse
Implementierungsmethode:
Erstellen Sie eine arrayMethods-Objekt mit Array.propertype als Prototyp und verwenden Sie dannObject.setPropertypeOf(o, arryMethods)Punkt o's __proto__ auf arrayMethods<p></p>
<img src="https://img.php.cn/%20upload/article/000/000/067/acd642f4f02e97980836bd636302ac44-0.png" alt="Analyse des auf Vue2- und Vue3-Daten reagierenden Prinzips und manuelle Implementierung (detaillierte Beispiele)"><p></p>So sammeln Sie Abhängigkeiten<p><img src="https://img.php.cn/upload/article/000/000/067/acd642f4f02e97980836bd636302ac44-1.png" alt="Analyse des auf Vue2- und Vue3-Daten reagierenden Prinzips und manuelle Implementierung (detaillierte Beispiele)">Verwenden Sie </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">function reactive(obj) {
const handler = {
get(target, prop, receiver) {
track(target, prop);
const value = Reflect.get(...arguments);
if(typeof value === 'Object') {
reactive(value)
}else {
return value }
},
set(target,key, value, receiver) {
trigger(target,key, value);
return Reflect.set(...arguments);
},
};
return new Proxy(obj,handler)}function track(data, key) {
console.log("sue set", data, key);}function trigger(data, key,value) {
console.log("sue set", key,':',value);}const dinner = {
name:'haochi1'}const proxy =reactive(dinner)proxy.name
proxy.list = []proxy.list.push(1)</pre><div class="contentsignin">Nach dem Login kopieren</div></div>
<p>Die Daten <code>name
werden verwendet In dieser Vorlage müssen wir die Datenattribute beobachten, um die Orte zu benachrichtigen, an denen sie verwendet werden. Dies bedeutet, dass wir zuerst Abhängigkeiten sammeln müssen, dh die Orte, an denen sich der Datenname befindet verwendet, und wenn sich die Daten ändern, wird die zuvor erfasste Abhängigkeitsschleife ausgelöst. Zusammenfassend werden Abhängigkeiten in Gettern gesammelt und Abhängigkeiten in Settern ausgelöst.
Proxy verwenden
handler
p
bei der Ausführung verschiedener Operationen. defineProperty
DifferencedefineProperty
s Eigenschaften müssen durchlaufen werden, um alle Eigenschaften zu überwachenVerwenden Sie einen Proxy, um alle Eigenschaften des Objekts als Proxy zu verwenden.Das obige ist der detaillierte Inhalt vonAnalyse des auf Vue2- und Vue3-Daten reagierenden Prinzips und manuelle Implementierung (detaillierte Beispiele). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!