
Vorwort
vue3
Es stand seit seiner Veröffentlichung zwei Jahre lang im Rampenlicht und hat jetzt die Dynamik, die Welt mit React zu teilen. Wir wissen, dass es auf der Fähigkeit des Proxys basiert, Reaktionsfähigkeit zu erreichen, was einige vue2
der verbleibenden Probleme gelöst hat Gleichzeitig hat es aufgrund der Eigenschaften des Proxys auch die Laufzeitleistung verbessert
Alles hat Vor- und Nachteile. proxy
Obwohl es unbesiegbar ist, hat es auch seine eigenen Einschränkungen, was meiner Meinung nach zu einigen Nachteilen führt (tatsächlich entspricht es nicht der natürlichen Schreibweise der js-Sprache, manche Leute denken, es sei etwas Besonderes Schreibweise, und er gehört nicht zu den Nachteilen)
-
1. Die Implementierung des responsiven Systems von primitiven Werten führt dazu, dass es als Objekt gepackt und mittels zugegriffen .value
werden -
2. ES6-Destrukturierung kann nicht beliebig verwendet werden. würde seine reaktionsschnelle Natur brechen
Getrieben von meiner Neugier recherchierte und grübelte ich darüber nach, warum er diese beiden Nachteile verursachte
Implementierung eines reaktiven Systems für primitive Werte
Bevor wir die Implementierung eines reaktiven Systems primitiver Werte verstehen, wollen wir uns zuerst die Fähigkeiten des Proxys ansehen!
const obj = {
name: 'win'
}
const handler = {
get: function(target, key){
console.log('get--', key)
return Reflect.get(...arguments)
},
set: function(target, key, value){
console.log('set--', key, '=', value)
return Reflect.set(...arguments)
}
}
const data = new Proxy(obj, handler)
data.name = 'ten'
console.log(data.name,'data.name22')
复制代码
Im obigen Code haben wir festgestellt, dass die Verwendung von Proxy selbst das Abfangen des Objekts new Proxy
ist und das Objekt obj durch den Rückgabewert von abgefangen wird
Auf diese Weise wird die get
Methode , und wenn Sie den Wert im Objekt ändern, wird die set
Methode ausgelöst
Aber was den ursprünglichen Wert angeht, hat er kein Interesse, was soll ich tun, es new proxy
kann nicht verwendet werden.
In der Verzweiflung können wir es nur einpacken, damit wir .value
Zugriff auf die Verwendung haben
Werfen wir einen Blick auf die konkrete Implementierung
import { reactive } from "./reactive";
import { trackEffects, triggerEffects } from './effect'
export const isObject = (value) => {
return typeof value === 'object' && value !== null
}
// 将对象转化为响应式的
function toReactive(value) {
return isObject(value) ? reactive(value) : value
}
class RefImpl {
public _value;
public dep = new Set; // 依赖收集
public __v_isRef = true; // 是ref的标识
// rawValue 传递进来的值
constructor(public rawValue, public _shallow) {
// 1、判断如果是对象 使用reactive将对象转为响应式的
// 浅ref不需要再次代理
this._value = _shallow ? rawValue : toReactive(rawValue);
}
get value() {
// 取值的时候依赖收集
trackEffects(this.dep)
return this._value;
}
set value(newVal) {
if (newVal !== this.rawValue) {
// 2、set的值不等于初始值 判断新值是否是对象 进行赋值
this._value = this._shallow ? newVal : toReactive(newVal);
// 赋值完 将初始值变为本次的
this.rawValue = newVal
triggerEffects(this.dep)
}
}
}
复制代码
Der obige Code stellt das Packen des Originalwerts dar. Er wird als Objekt gepackt, und auf den Originalwert wird über die Methoden get value
und zugegriffen, was zu der erforderlichen Operation führt, die eigentlich eine hilflose Wahl ist.set value
.value
相当于两瓶毒药,你得选一瓶
Man kann nicht Fisch und Bärentatze haben
Warum ES6 destrukturiert und nicht in der Lage ist, es zu verwenden, wird seine reaktionsschnellen Funktionen zerstören
Die erste Frage ist endlich verstanden, also schauen wir uns die zweitwichtigste Frage an,为什么结构赋值,会破坏响应式特性
Proxy-Hintergrund
Bevor wir beginnen, lassen Sie uns diskutieren, warum die Änderung响应式方案
Vue2 basiert auf Object.defineProperty , hat aber viele Mängel, wie z. B. die Unfähigkeit, die Änderung des Arrays basierend auf Indizes zu überwachen, und Mängel wie Map, Set, WeakMap und WeakSet werden nicht unterstützt .
Tatsächlich verzögern diese unsere Entwicklung nicht, vue2 ist immer noch der Mainstream,
Mein Verständnis ist 与时俱进
, dass 新一代的版本,一定要紧跟语言的特性,一定要符合新时代的书写风格
, obwohl proxy
es viele Verbesserungen im Vergleich zu Object.defineProperty gibt, es nicht ohne Mängel ist.不兼容IE
Wie kann es auf der Welt etwas Perfektes geben?
Dein großer Mut liegt darin, ein bisschen von der Gegenwart aufzugeben, um eine Zukunft aufzubauen!
Ausführungsprinzip
Nachdem wir den Hintergrund verstanden haben, lassen Sie uns das Prinzip in einem gefälschten Modus überprüfen proxy
, obwohl dies alles faul ist.
Worauf sollten Sie jedoch beim Schreiben von Hydrologie achten: zwei Wörter - Kohärenz

const obj = {
count: 1
};
const proxy = new Proxy(obj, {
get(target, key, receiver) {
console.log("这里是get");
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log("这里是set");
return Reflect.set(target, key, value, receiver);
}
});
console.log(proxy)
console.log(proxy.count)
复制代码
Der obige Code stellt die spezifische Art der Verwendung von Proxy dar. Durch die Zusammenarbeit mit Reflect kann das Abfangen von Objekten realisiert werden.

Mit einer solchen Abhängigkeit können Sie Reaktionsfähigkeit erreichen.Sie können feststellen, dass das gesamte Objekt dieses Objekts abgefangen wird, aber Sie stellen fest, dass das Objekt eine Ebene tiefer verschachtelt ist.
zum Beispiel:
const obj = {
count: 1,
b: {
c: 2
}
};
console.log(proxy.b)
console.log(proxy.b.c)
复制代码
Er kann nicht abfangen, wir müssen packen
const obj = {
a: {
count: 1
}
};
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
console.log("这里是get");
// 判断如果是个对象在包装一次,实现深层嵌套的响应式
if (typeof target[key] === "object") {
return reactive(target[key]);
};
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log("这里是set");
return Reflect.set(target, key, value, receiver);
}
});
};
const proxy = reactive(obj);
复制代码
Nun, das Prinzip ist erledigt, lasst es uns formell studieren
Um nun einige mir bekannte Situationen aufzulisten, in denen die Reaktionsfähigkeit verloren geht:
-
1. Dekonstruieren Sie das props
Objekt, weil es seine Reaktionsfähigkeit verliert -
2. Direkte Zuweisung reactive
von reaktiven Objekten -
3. vuex
Mittlere Kombination API-Zuweisung
Destrukturieren von props
Objekten, weil es die Reaktionsfähigkeit verliert
const obj = {
a: {
count: 1
},
b: 1
};
//reactive 是上文中的reactive
const proxy = reactive(obj);
const {
a,
b
} = proxy;
console.log(a)
console.log(b)
console.log(a.count)
复制代码

Im obigen Code finden wir, dass die destrukturierende Zuweisung, b 不会触发响应式
, a如果你访问的时候
, die Antwort auslöst
Warum ist das?
Keine Sorge, lass es uns nacheinander erklären?
Lassen Sie uns zuerst diskutieren, warum die Destrukturierung der Zuweisung die Reaktionsfähigkeit verliert?
Wir kennen die destrukturierende Zuweisung, die Unterscheidung zwischen der Zuweisung von primitiven Typen und der Zuweisung von Referenztypen,
原始类型的赋值相当于按值传递
,引用类型的值就相当于按引用传递
ist äquivalent zu
// 假设a是个响应式对象
const a={ b:1}
// c 此时就是一个值跟当前的a 已经不沾边了
const c=a.b
// 你直接访问c就相当于直接访问这个值 也就绕过了 a 对象的get ,也就像原文中说的失去响应式
复制代码
Warum a
reagiert es also?
Da a
es sich um einen Referenztyp handelt, erinnern wir uns an ein Urteil im obigen Code. Wenn er ein object
ist, verpacken Sie ihn als reaktiv
Wenn es sich um einen Referenztyp handelt, verlieren Sie formal aufgrund der aktuellen Funktion nicht die Reaktionsfähigkeit, wenn Sie auf seinen Inhalt zugreifen
// 假设a是个响应式对象
const a={ b:{c:3}}
// 当你访问a.b的时候就已经重新初始化响应式了,此时的c就已经是个代理的对象
const c=a.b
// 你直接访问c就相当于访问一个响应式对象,所以并不会失去响应式
复制代码
Das Obige erklärt grob, warum eine destrukturierende Zuweisung die Reaktionsfähigkeit verlieren kann. Ich schätze, das Dokument ist zu faul, um den Grund zu erklären, also stelle ich einfach eine Regel auf, Sie!
Verwenden Sie es nicht, speichern Sie die Fehler, die Sie für vue
wahr halten, und ändern Sie die Nutzungsgewohnheiten des Benutzers im Voraus! nicht gewohnt
Direkte Zuweisung reactive
von reaktiven Objekten
Als wir vue3 zum ersten Mal verwendet haben, haben wir angegeben, dass der folgende Code geschrieben werden würde
const vue = reactive({ a: 1 })
vue = { b: 2 }
复制代码
Und dann Fragen zu stellen, reactive
ist es nicht reaktionsschnell? Warum verschwand seine Reaktionsfähigkeit, nachdem ich den Wert zugewiesen hatte, und dann schrie er, Müll vue
Tatsächlich liegt dies daran, dass Sie das Konzept von js native nicht klarstellen, tatsächlich haben 尤大
Sie die größten Anstrengungen unternommen, um Fehler zu vermeiden
Beispielsweise verbietet er aufgrund des Problems der destrukturierenden Zuweisung direkt die reaktive destrukturierende Zuweisung

Wenn Sie die destrukturierende Zuweisungsoperation verwenden, wird sie direkt deaktiviert
Dann fragte jemand wieder, 为啥props 不给禁用了呢
?
因为你的props 的数据可能不是响应式的啊,不是响应式的,我得能啊
, insbesondere kann er die Verwendung der neuen Syntax durch den Benutzer nicht stören.
Es ist also derselbe Satz: 框架现在的呈现,其实充满了取舍
„Manchmal sind es wirklich zwei Flaschen Gift, nimm eine!
Zurück zum Thema, sprechen wir über native js-Syntax
Als erstes ist zu bestätigen, dass die Zuordnung des Referenztyps des nativen js tatsächlich auf der Referenzadresse basiert!
// 当reactive 之后返回一个代理对象的地址被vue 存起来,
// 用一个不恰当的比喻来说,就是这个地址具备响应式的能力
const vue = reactive({ a: 1 })
// 而当你对于vue重新赋值的时候不是将新的对象赋值给那个地址,而是将vue 换了个新地址
// 而此时新地址不具备响应式,可不就失去响应式了吗
vue = { b: 2 }
复制代码
Das Obige ist reactive
die Erklärung für den Verlust der Reaktionsfähigkeit, daher ist dies auch der Grund, warum viele Benutzer fluchen.不符合他的使用习惯了,这都是被vue2 培养起来的一代
Hier möchte ich ein faires Wort für dich sagen, Da 人家又没收你钱,还因为他,你有口饭吃
,
Du selbst kannst nicht mit der Zeit gehen und dich auf Neues einlassen, das bist du 能耐
,
das ist typisch端起碗吃肉,放下筷子骂娘
vuex
API-Zuweisung für mittlere Zusammensetzung
Die Verwendung von Zuweisungen in vuex kann auch die Reaktionsfähigkeit beeinträchtigen
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup () {
const store = useStore()
return {
// 在 computed 函数中访问 state
count: computed(() => store.state.count),
// 在 computed 函数中访问 getter
double: computed(() => store.getters.double)
}
}
}
复制代码
Im obigen Code haben wir festgestellt, dass das mit umschlossen store.getters.double
werden muss computed
. Tatsächlich ist der Grund derselbe und es ist auch der Grund für die Variablenzuweisung. Wir werden sie hier nicht wiederholen!
zu guter Letzt
Dieser Artikel enthält im Prozess der Verwendung von vue3 einige Erfahrungen und Erkundungen nach dem Mining. Ich hoffe, er wird Ihnen hilfreich sein, damit Sie eine Beförderung und Gehaltserhöhung bei der Arbeit erhalten!
Abschließend möchte ich meine vue-Quellcodeanalyse fördern. Die Analyse ist vielleicht nicht sehr gut, aber es wird alles Zeile für Zeile gelesen. Vielleicht fällt Ihnen nach dem Lesen ein Satz oder ein Satz ein, was hilfreich ist!
Quellcode-Analyseadresse [1]
Willkommen Stern
Über diesen Artikel
Autor: Lao Ji Bauer
https://juejin.cn/post/7114596904926740493
Das Ende
》》Die Fragendatenbank, die Interviewer verwenden, kommen Sie und sehen Sie 《》
Liken am Ende nicht vergessen!
Viel Glück im Jahr 2022! Gewaltige Schönheit! Heftig dünn!