亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue3響應式原理和api編寫的方法是什么

發布時間:2021-12-10 15:03:40 來源:億速云 閱讀:153 作者:iii 欄目:編程語言

這篇文章主要講解了“vue3響應式原理和api編寫的方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vue3響應式原理和api編寫的方法是什么”吧!

前言

vue3響應式原理加api編寫,快速明白vue3響應式原理


vue3響應式原理實現

先寫一段代碼看下

實現effect

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歲

看看有什么可以優化的點呢?

首先:多個函數,在age發生變化后需要手動再次調用多個函數才可以獲取最新信息

期望可以修改信息以后自動調用多個函數

如何實現呢

可以想到將多個函數存放到一起存放到gather函數,并且讓age發生變化時可以將多個函數調用trigger調用

實現gather及trigger

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歲

再繼續看下還是有什么可以優化的點

如果變量是一個對象或多個對象的話該怎么處理呢

  • 變量為原始類型時Set存儲

  • 變量為對象時可以用map存儲

  • 多個對象時用weakMap存儲

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歲

在繼續看看有哪些可以優化的點

上邊依賴的收集gather以及函數的更新通知trigger每次都是手動收集手動觸發更新,那有什么方法可以自動收集及觸發嗎

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也實現下

ref

在vue3中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
        }
    )
}

感謝各位的閱讀,以上就是“vue3響應式原理和api編寫的方法是什么”的內容了,經過本文的學習后,相信大家對vue3響應式原理和api編寫的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

岱山县| 民勤县| 揭阳市| 自贡市| 新绛县| 青海省| 丽江市| 南城县| 甘南县| 凤翔县| 泰宁县| 丰镇市| 重庆市| 鲁山县| 马龙县| 沽源县| 永嘉县| 通许县| 县级市| 玛曲县| 哈密市| 五峰| 辽阳市| 化州市| 同心县| 客服| 北川| 商南县| 开远市| 闽清县| 乐陵市| 社旗县| 诏安县| 寻甸| 邵阳市| 遂宁市| 东丰县| 汾西县| 赤水市| 容城县| 黔西县|