Rumah > Artikel > hujung hadapan web > Apakah prinsip tindak balas Vue3
API teras Proksi bergantung pada prinsip reaktif Vue3 boleh digunakan untuk memintas beberapa operasi objek.
const obj = { a: 1 }; const p = new Proxy(obj, { get(target, property, receiver) { console.log("get"); return Reflect.get(target, property, receiver); }, set(target, property, value, receiver) { console.log("set"); return Reflect.set(target, property, receiver); }, has(target, prop) { console.log("has"); return Reflect.has(target, prop); }, deleteProperty(target, prop) { console.log("deleteProperty"); return Reflect.deleteProperty(target, prop); }, }); p.a; // 输出 --> get p.a = 2; // 输出 --> set "a" in p; // 输出 --> has delete p.a; // 输出 --> deleteProperty
Seperti yang ditunjukkan dalam contoh di atas, kami menggunakan Proksi untuk memproksi akses harta, penetapan harta, dalam pengendali dan memadamkan operasi objek Obj dan melaksanakan output console.log.
Reflect ialah API yang digunakan bersama dengan Proxy Apabila kami merampas operasi tertentu, jika kami perlu mencerminkan operasi ini, kami memerlukan Reflect API.
Memandangkan kami memintas operasi objek, fungsi operasi ini hilang Contohnya, mengakses atribut p.a sepatutnya mendapat nilai atribut, tetapi tidak akan ada hasil pada masa ini kita masih Jika kita ingin mempunyai fungsi sebelum pemintasan, kita perlu menggunakan Reflect untuk mencerminkan kembali.
const obj = { a: 1 }; const p = new Proxy(obj, { get(target, property, receiver) { console.log("get"); return Reflect.get(target, property, receiver); }, set(target, property, value, receiver) { console.log("set"); return Reflect.set(target, property, receiver); }, has(target, prop) { console.log("has"); return Reflect.has(target, prop); }, deleteProperty(target, prop) { console.log("deleteProperty"); return Reflect.deleteProperty(target, prop); }, });
Kami akan menggunakan contoh ini untuk menerangkan prinsip responsif Vue3 sepanjang teks berikut.
<div id="app"></div> <script> // 创建一个响应式对象 const state = reactive({ counter: 1 }); // 立即运行一个函数,当响应式对象的属性发生改变时重新执行。 effect(() => { document.querySelector("#app").innerHTML = state.counter; }); // 2s 后视图更新 setTimeout(() => { state.counter += 1; }, 2000); </script>
Kami menggunakan reaktif untuk mencipta keadaan objek reaktif dan memanggil kaedah kesan, yang menerima fungsi kesan sampingan Perlaksanaan kesan akan segera memanggil fungsi kesan sampingan dan menetapkan state.counter kepada #app ; selepas dua saat, state.counter += 1. Pada masa ini, fungsi kesan sampingan kesan akan dilaksanakan semula dan halaman akan menjadi 2.
Proses pelaksanaan dalaman secara kasar seperti yang ditunjukkan dalam rajah di bawah:
Panggil reactive() untuk mengembalikan objek Proksi dan merampas operasi dapatkan dan tetapkan objek
Kaedah kesan panggilan (), state.counter hartanah akan diakses dan operasi dapatkan proksi akan dicetuskan.
Kaedah get akan memanggil track() untuk mengumpul kebergantungan; 🎜>
const reactive = (target) => { return new Proxy(target, { get(target, key, receiver) { const res = Reflect.get(target, key, receiver); track(target, key); // 收集依赖 if (isObject(res)) { // 如果当前获取的属性值是一个对象,则继续将为此对象创建 Proxy 代理 return reactive(res); } return res; }, set(target, key, value, receiver) { Reflect.set(target, key, value, receiver); trigger(target, key); // 依赖更新 }, }); };
effect
let activeEffect; function effect(fn) { const _effect = function reactiveEffect() { activeEffect = _effect; fn(); }; _effect(); }
effect(() => { // effect 的立即执行会访问 state.counter,触发了对象的 get 操作。 document.querySelector("#app").innerHTML = state.counter; });
track
const targetMap = new WeakMap(); function track(target, key) { if (!activeEffect) { return; } let depsMap = targetMap.get(target); if (!depsMap) { targetMap.set(target, (depsMap = new Map())); } let dep = depsMap.get(key); if (!dep) { depsMap.set(key, (dep = new Set())); } if (!dep.has(activeEffect)) { dep.add(activeEffect); } }
Selepas pelaksanaan selesai, kita mendapat A struktur data seperti berikut:
[ // map 集合 { key: {counter: 1} // state 对象, value: [ // map 集合 { key: "counter", value: [ // set function reactiveEffect() {} // effect 副作用函数 ], } ], }, ];
Nota: Apabila kita memanggil kesan, fungsi kesan sampingan semasa akan diberikan kepada activeEffect global, jadi kita boleh mengaitkan kebergantungannya dengan betul pada masa ini.
cetus
setTimeout(() => { // 给 counter 属性赋值会触发 set 操作 state.counter += 1; }, 2000);
function trigger(target, key) { const depsMap = targetMap.get(target); if (!depsMap) return; const effects = depsMap.get(key); effects && effects.forEach((effect) => effect()); }
Atas ialah kandungan terperinci Apakah prinsip tindak balas Vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!