ホームページ > 記事 > ウェブフロントエンド > vue3の応答原理とAPIの書き方の分析
vue3 レスポンシブ原則と API 記述、vue3 レスポンシブ原則をすぐに理解する
GitHub ブログ: https://github 。 com/jiejiangzi/blog/issues/8
vue3 レスポンシブ原則の実装
最初にコードを書いて見てみましょう
効果の実装
var name = 'sl', age = 22; effect1 = () => `我叫${name},今年${age}岁` effect2 = () => `我叫${name},今年${age+1}岁` console.log(effect1()) //我叫sl,今年22岁 console.log(effect2()) //我叫sl,今年23岁 age = 30; console.log(effect1()) //我叫sl,今年30岁 console.log(effect2()) //我叫sl,今年31岁
何を最適化できるか見てみましょう。
まず第一に、複数の関数です。年齢が変更された後、最新の情報を取得するには、複数の関数を手動で再度呼び出す必要があります。
複数の関数は、年齢が変更された後、自動的に呼び出せることが期待されます。
実装方法
gather関数に複数の関数をまとめて格納しておき、時代が変わったときに複数の関数を呼び出すことが考えられます。トリガー呼び出し
収集とトリガーを実装します
var name = "sl", age = 22; var tom, joy; effect1 = () => (tom = `我叫${name},今年${age}岁`); effect2 = () => (joy = `我叫${name},今年${age + 1}岁`); var dep = new Set(); function gather() { dep.add(effect1); dep.add(effect2); } function trigger() { dep.forEach((effect) => effect()); } gather(); effect1() effect2() console.log(tom); //我叫sl,今年22岁 console.log(joy); //我叫sl,今年23岁 age = 30; trigger() console.log(tom); //我叫sl,今年30岁 console.log(joy); //我叫sl,今年31岁
続けて、最適化できる点があるかどうか確認しましょう
変数が 1 つのオブジェクトまたは複数のオブジェクトの場合はどうするか
変数がプリミティブ型の場合はストレージを設定します
var obj1 = { name: "tom", age: 22 }; var obj2 = { name: "joy", age: 23 }; var tom, joy; effect1 = () => (tom = `我叫${obj1.name},今年${obj1.age}岁`); effect2 = () => (joy = `我叫${obj2.name},今年${obj2.age}岁`); var depsMap = new WeakMap(); function gather(target, key) { let depMap = depsMap.get(target); if (!depMap) { depsMap.set(target, (depMap = new Map())); } let dep = depMap.get(key); if (!dep) { depMap.set(key, (dep = new Set())); } if (target === obj1) { dep.add(effect1); } else { dep.add(effect2); } } function trigger(target, key) { let depMap = depsMap.get(target); if (depMap) { const dep = depMap.get(key); if (dep) { dep.forEach((effect) => effect()); } } } gather(obj1, "age");//收集依赖 gather(obj2, "age");//收集依赖 effect1(); effect2(); console.log(tom); //我叫sl,今年22岁 console.log(joy); //我叫sl,今年23岁 obj1.age = 30; obj2.age = 10; trigger(obj1, "age"); trigger(obj2, "age"); console.log(tom); //我叫sl,今年30岁 console.log(joy); //我叫sl,今年31岁どの点が最適化できるかを見てみましょう上記に依存するコレクション収集と関数更新通知トリガーは手動で収集され、毎回更新がトリガーされます。
Proxy
を自動的に収集してトリガーする方法はありますか? ##reactive を実装する #最初に reactive 関数を作成します
function reactive(target) { const handle = { set(target, key, value, receiver) { Reflect.set(target, key, value, receiver); trigger(receiver,key) // 设置值时触发自动更新 }, get(target, key, receiver) { gather(receiver, key); // 访问时收集依赖 return Reflect.get(target, key, receiver); }, }; return new Proxy(target, handle); }
次に、reactive 関数を前のコードに適用します
var obj1 = reactive({ name: "tom", age: 22 }); var obj2 = reactive({ name: "joy", age: 23 }); var tom, joy; effect1 = () => (tom = `我叫${obj1.name},今年${obj1.age}岁`); effect2 = () => (joy = `我叫${obj2.name},今年${obj2.age}岁`); var depsMap = new WeakMap(); function gather(target, key) { let depMap = depsMap.get(target); if (!depMap) { depsMap.set(target, (depMap = new Map())); } let dep = depMap.get(key); if (!dep) { depMap.set(key, (dep = new Set())); } if (target === obj1) { dep.add(effect1); } else { dep.add(effect2); } } function trigger(target, key) { let depMap = depsMap.get(target); if (depMap) { const dep = depMap.get(key); if (dep) { dep.forEach((effect) => effect()); } } } effect1(); effect2(); console.log(tom); //我叫sl,今年22岁 console.log(joy); //我叫sl,今年23岁 obj1.age = 30; obj2.age = 10; console.log(tom); //我叫sl,今年30岁 console.log(joy); //我叫sl,今年31岁
次に、別の問題が発生します。 Gather 関数内にハードコーディングされた dep 追加関数があります
これを解決するにはどうすればよいですか?Effect 関数を書き換えます
let activeEffect = null function effect(fn) { activeEffect = fn; activeEffect(); activeEffect = null; // 执行后立马变成null } var depsMap = new WeakMap(); function gather(target, key) { // 避免例如console.log(obj1.name)而触发gather if (!activeEffect) return; let depMap = depsMap.get(target); if (!depMap) { depsMap.set(target, (depMap = new Map())); } let dep = depMap.get(key); if (!dep) { depMap.set(key, (dep = new Set())); } dep.add(activeEffect) //将函数添加到依赖 } effect(effect1); effect(effect2);
reactive も実装されており、ref も実装されています
refvue3 で ref を使用する方法
var name = ref('tom')
console.log(name.value) // tom
値を取得するには .value を使用する必要があります
function ref(name){ return reactive( { value: name } ) } const name = ref('tom'); console.log(name.value) //tom完全なコード
var activeEffect = null;
function effect(fn) {
activeEffect = fn;
activeEffect();
activeEffect = null;
}
var depsMap = new WeakMap();
function gather(target, key) {
// 避免例如console.log(obj1.name)而触发gather
if (!activeEffect) return;
let depMap = depsMap.get(target);
if (!depMap) {
depsMap.set(target, (depMap = new Map()));
}
let dep = depMap.get(key);
if (!dep) {
depMap.set(key, (dep = new Set()));
}
dep.add(activeEffect)
}
function trigger(target, key) {
let depMap = depsMap.get(target);
if (depMap) {
const dep = depMap.get(key);
if (dep) {
dep.forEach((effect) => effect());
}
}
}
function reactive(target) {
const handle = {
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
trigger(receiver, key); // 设置值时触发自动更新
},
get(target, key, receiver) {
gather(receiver, key); // 访问时收集依赖
return Reflect.get(target, key, receiver);
},
};
return new Proxy(target, handle);
}
function ref(name){
return reactive(
{
value: name
}
)
}
最新の 5 つの vue.js ビデオ チュートリアルの選択
以上がvue3の応答原理とAPIの書き方の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。