Die Reaktionsfähigkeit von vue3 kann nicht von Proxy
getrennt werden von Proxy
ist untrennbar mit Reflect
verbunden. Gleichzeitig stellen sie im Bereich der Programmierung auch zwei Entwurfsmuster dar, nämlich Proxy und Reflexion. Proxy
,说到Proxy
则离不开Reflect
.这两个对象是ES6新增的对象,同时在编程领域,他们也代表着2种设计模式,即代理与反射。
Proxy
可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须经过这层拦截,而我们就可以通过这层拦截去改变目标对象的内容或者行为,或者叫过滤和控制。这个词本意就是代理,好比一个代理人站在神奇,我们所有行为都会被他过滤,可能我们说的话,经过代理人一说,意思就变了。
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
var proxy = new Proxy(target, handler);
其中target
表示要代理的那个对象,handler
则是表示我们需要拦截的行为,这里直接放一张阮一峰的截图。
Reflect
中文译为:反射。如果说Proxy
是有一个代理人站在身前面,帮你拦截并处理一些行为,那么Reflect
就是你身后的一面镜子,它能看见真实的自己。
而你自己,就是一个类或者对象,或者一个函数,只要是js中存在的,都能被Proxy
和 Reflect
处理。
它的操作和Proxy
正好相反,但却一一对应。比如我们获取对象中一个属性。
const obj = {foo:1} const a = Reflect.get(obj, 'foo')
这一小节主要是介绍了Proxy与Reflect,后面会有一个应用老告诉你为什么Proxy与Reflect与响应式数据息息相关。
看完了Proxy
与Reflect
的基本使用之后,我们实践一下。
我们曾经写过这样的代码
const reactive = (object)=>{ return new Proxy(object,{ get(target,key){ track(target,key) return target[key] } set(target,key, newVal){ target[key] = newVal trigger(target,key) return true } }) }
其实就是用Proxy
代理了对象读和取操作,在读的时候收集依赖,在取的时候触发响应。看起来似乎没有问题,那么我们再试继续往下写
const obj = { a:1, get b(){ return this.a } } const data = reactive(obj) effect(()=>{ console.log(data.b) }) setTimeOut(()=>{ data.b++ },500)
这里我们没有用一般的对象写法,而是通过访问器为它新增了一个b属性.之后,我们先把这个对象转换为响应式对象,再给他们设定一个响应式的回调,然后在冬天改变他的值,理论上这时候应该会执行副作用函数,但是实际上呢,根本不会执行。
我们回顾一下之前写的reactive
方法,在里面返回的是target[key]
,当我们的target是obj,key是b的时候,那个this会是谁呢?因为target是原始对象,也就是obj,根据谁调用是谁的原则,这个this也就指向了obj。obj是响应式对象吗,显然不是,那个b也就永远不会执行副作用函数,响应式就失效了。
这里其实就是this的指向问题,你可能会说一般人怎么会用getter去赋值属性呢,但是这个作为一个简单的case,甚至都算不上边界,我们需要解决它。
解决的方法也很简单,就是通过Reflect
。这也是为什么我说Proxy
与Reflect
就是焦不离孟 孟不离焦. 我们的reactive,get的时候,加入第三个参数receiver
get(target,key){ track(target,key,receiver) return Reflect.get(target,key,receiver) }
我这里理解的是,receiver
就相当于函数的bind
方法,它改变的this的执行,当我们同过Reflect
读取值的时候,this的指向被改为receiver
,而Reflect
时的receiver
又是Proxy
中的入参,它执行了这个Proxy
Proxy
kann als Einrichtung einer „Abfangschicht“ vor dem Zielobjekt verstanden werden Durchlaufen Sie diese Abfangebene, und wir können diese Abfangebene verwenden, um den Inhalt oder das Verhalten des Zielobjekts zu ändern oder zu filtern und zu steuern. Die ursprüngliche Bedeutung dieses Wortes ist Handlungsfähigkeit, genau wie ein Agent, der in der Magie steht, alle unsere Handlungen werden von ihm gefiltert. Vielleicht ändert sich die Bedeutung dessen, was wir sagen, nachdem der Agent es gesagt hat. #🎜🎜##🎜🎜#ES6 bietet nativ einen Proxy-Konstruktor zum Generieren von Proxy-Instanzen. #🎜🎜#rrreee#🎜🎜# Unter diesen stellt target
das zu vermittelnde Objekt dar und handler
stellt das Verhalten dar, das wir abfangen müssen. Hier ist ein Bild von Ruan Yifeng-Screenshot. #🎜🎜##🎜🎜##🎜🎜#Reflect
Die chinesische Übersetzung lautet: Reflexion. Wenn Proxy
so ist, als ob ein Agent vor Ihnen steht, der Ihnen hilft, bestimmte Verhaltensweisen abzufangen und zu bewältigen, dann ist Reflect
ein Spiegel hinter Ihnen, der Ihr wahres Selbst sehen kann. #🎜🎜##🎜🎜#Und Sie selbst sind eine Klasse, ein Objekt oder eine Funktion. Solange es in js existiert, kann es von Proxy
und Reflect
verarbeitet werden . #🎜🎜##🎜🎜##🎜🎜##🎜🎜# Seine Funktionsweise ist genau das Gegenteil von Proxy
, entspricht aber eins zu eins. Beispielsweise erhalten wir ein Attribut in einem Objekt. #🎜🎜#rrreee#🎜🎜#In diesem Abschnitt werden hauptsächlich Proxy und Reflect vorgestellt. Später wird eine Anwendung erläutert, warum Proxy, Reflect und reaktionsfähige Daten eng miteinander verbunden sind. #🎜🎜##🎜🎜#Übungsbeispiel#🎜🎜##🎜🎜#Nachdem wir die grundlegende Verwendung von Proxy
und Reflect
gelesen haben, üben wir es. #🎜🎜##🎜🎜#Wir haben einmal Code wie diesen geschrieben#🎜🎜#rrreee#🎜🎜#Tatsächlich verwenden wir Proxy
, um Lese- und Abrufvorgänge von Objekten zu vertreten und Abhängigkeiten während des Lesens zu sammeln. Löst beim Abrufen eine Antwort aus. Es scheint kein Problem zu geben, dann versuchen wir es noch einmal und schreiben weiter #🎜🎜#rrreee#🎜🎜#Hier verwenden wir nicht die allgemeine Methode zum Schreiben von Objekten, sondern fügen über den Accessor ein neues b-Attribut hinzu. Wir konvertieren dieses Objekt zunächst in ein reaktionsfähiges Objekt, legen einen reaktionsfähigen Rückruf für sie fest und ändern dann seinen Wert im Winter. Theoretisch sollte die Nebeneffektfunktion zu diesem Zeitpunkt ausgeführt werden, tatsächlich wird sie jedoch überhaupt nicht ausgeführt . #🎜🎜##🎜🎜# Sehen wir uns die zuvor geschriebene reaktive
-Methode an. Was darin zurückgegeben wird, ist target[key]
. Wenn unser Ziel obj ist, ist es der Schlüssel ist Wann b, wer wird das sein? Da das Ziel das ursprüngliche Objekt ist, das obj ist, weist dies nach dem Prinzip „Wer wen anruft“ auch auf obj hin. Ist obj ein reaktionsfähiges Objekt? Offensichtlich nicht, dass b die Nebeneffektfunktion niemals ausführt und die Reaktionsfähigkeit ungültig ist. #🎜🎜##🎜🎜#Das ist eigentlich das Zeigeproblem. Sie fragen sich vielleicht, wie normale Leute Getter verwenden, um Eigenschaften zuzuweisen, aber als einfachen Fall ist dies nicht einmal eine Grenze. Wir müssen es lösen. #🎜🎜##🎜🎜#Die Lösung ist auch sehr einfach, nämlich durch Reflect
. Aus diesem Grund sage ich, dass Proxy
und Reflect
untrennbar miteinander verbunden sind. Beim Abrufen fügt unser Reaktiv den dritten Parameter receiver
#🎜🎜#rrreee# hinzu. 🎜🎜#Was ich hier verstehe, ist, dass receiver
der bind
-Methode der Funktion entspricht. Sie ändert die Ausführung davon, wenn wir Reflect liest einen Wert, dessen Zeiger in <code>receiver
und receiver
geändert wird, wenn Reflect
der Eingabeparameter in ist Proxy
führt diesen Proxy
aus und ändert dadurch den Zeiger davon im vorherigen Artikel von obj auf data, sodass die Antwort nicht verloren geht. #🎜🎜#Das obige ist der detaillierte Inhalt vonSo verwenden Sie vue3 responsive Proxy und Reflect. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!