解析vue3響應式原理以及api編寫
前言
vue3響應式原則加api編寫,快速明白vue3響應式原理
GitHub博客:https://github .com/jiejiangzi/blog/issues/8
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 } ) }
推薦學習:《最新的5個vue.js影片教學精選》
以上是解析vue3響應式原理以及api編寫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如何在PHP專案中透過呼叫API介面來實現資料的爬取與處理?一、介紹在PHP專案中,我們經常需要爬取其他網站的數據,並對這些數據進行處理。而許多網站提供了API接口,我們可以透過呼叫這些接口來取得資料。本文將介紹如何使用PHP來呼叫API接口,實現資料的爬取與處理。二、取得API介面的URL和參數在開始之前,我們需要先取得目標API介面的URL以及所需的

Oracle是一家全球知名的資料庫管理系統供應商,其API(ApplicationProgrammingInterface,應用程式介面)是一種強大的工具,可協助開發人員輕鬆地與Oracle資料庫互動和整合。在本文中,我們將深入探討OracleAPI的使用指南,向讀者展示如何在開發過程中利用資料介面技術,同時提供具體的程式碼範例。 1.Oracle

ReactAPI呼叫指南:如何與後端API進行互動和資料傳輸概述:在現代的Web開發中,與後端API進行互動和資料傳輸是一個常見的需求。 React作為一個流行的前端框架,提供了一些強大的工具和功能來簡化這個過程。本文將介紹如何使用React來呼叫後端API,包括基本的GET和POST請求,並提供具體的程式碼範例。安裝所需的依賴:首先,確保在專案中安裝了Axi

標題:如何處理LaravelAPI報錯問題,需要具體程式碼範例在進行Laravel開發時,常會遇到API報錯的情況。這些報錯可能來自於程式碼邏輯錯誤、資料庫查詢問題或是外部API請求失敗等多種原因。如何處理這些報錯是一個關鍵的問題,本文將透過具體的程式碼範例來示範如何有效處理LaravelAPI報錯問題。 1.錯誤處理在Laravel

OracleAPI整合策略解析:實現系統間無縫通信,需要具體程式碼範例在當今數位化時代,企業內部系統之間需要相互通信和資料共享,而OracleAPI就是幫助實現系統間無縫通信的重要工具之一。本文將從OracleAPI的基本概念和原則入手,探討API整合的策略,最終給出具體的程式碼範例幫助讀者更好地理解和應用OracleAPI。一、OracleAPI基本

開發建議:如何利用ThinkPHP框架進行API開發隨著網際網路的不斷發展,API(ApplicationProgrammingInterface)的重要性也日益凸顯。 API是不同應用程式之間進行通訊的橋樑,它可以實現資料共享、功能呼叫等操作,為開發者提供了相對簡單且快速的開發方式。而ThinkPHP框架作為一款優秀的PHP開發框架,具有高效能、可擴展且易用

在資料驅動的應用程式和分析領域,API(應用程式介面)在從各種來源檢索資料方面發揮著至關重要的作用。使用API資料時,通常需要以易於存取和操作的格式儲存資料。其中一種格式是CSV(逗號分隔值),它允許有效地組織和儲存表格資料。本文將探討使用強大的程式語言Python將API資料儲存為CSV格式的過程。透過遵循本指南中概述的步驟,我們將學習如何從API中檢索資料、提取相關資訊並將其儲存在CSV檔案中以供進一步分析和處理。讓我們深入了解使用Python進行API資料處理的世界,並釋放CSV格式的潛

vue3的生命週期:1、beforeCreate;2、created;3、beforeMount;4、mounted;5、beforeUpdate;6、updated;7、beforeDestroy;8、destroyed;9、activated;10、deactivated;11、errorCaptured;12 、getDerivedStateFromProps 等等
