Vue3的響應式原理解析

Vue3的響應式原理解析

Vue2響應式原理回顧
// 1.對象響應化:遍歷每個key,定義getter、setter
// 2.數組響應化:覆蓋數組原型方法,額外增加通知邏輯
const originalProto = Array.prototype
const arrayProto = Object.create(originalProto);['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort'].forEach(method => {arrayProto[method] = function () {originalProto[method].apply(this, arguments)notifyUpdate()}})
function observe (obj) {if (typeof obj !== 'object' || obj == null) {return}// 增加數組類型判斷,若是數組則覆蓋其原型if (Array.isArray(obj)) {Object.setPrototypeOf(obj, arrayProto)} else {const keys = Object.keys(obj)for (let i = 0; i < keys.length; i++) {const key = keys[i]defineReactive(obj, key, obj[key])}}
}
function defineReactive (obj, key, val) {observe(val) // 解決嵌套對象問題Object.defineProperty(obj, key, {get () {return val},set (newVal) {if (newVal !== val) {observe(newVal) // 新值是對象的情況val = newValnotifyUpdate()}}})
}
function notifyUpdate () {console.log('頁面更新!')
}

vue2響應式弊端:
響應化過程需要遞歸遍歷,消耗較大
新加或刪除屬性無法監聽
數組響應化需要額外實現
Map、Set、Class等無法響應式
修改語法有限制

Vue3響應式原理剖析

vue3使用ES6的Proxy特性來解決這些問題。

function reactive (obj) {if (typeof obj !== 'object' && obj != null) {return obj}// Proxy相當于在對象外層加攔截// http://es6.ruanyifeng.com/#docs/proxyconst observed = new Proxy(obj, {get (target, key, receiver) {// Reflect用于執行對象默認操作,更規范、更友好// Proxy和Object的方法Reflect都有對應// http://es6.ruanyifeng.com/#docs/reflectconst res = Reflect.get(target, key, receiver)console.log(`獲取${key}:${res}`)return res},set (target, key, value, receiver) {const res = Reflect.set(target, key, value, receiver)console.log(`設置${key}:${value}`)return res},deleteProperty (target, key) {const res = Reflect.deleteProperty(target, key)console.log(`刪除${key}:${res}`)return res}})return observed
}
//代碼測試
const state = reactive({foo: 'foo',bar: { a: 1 }
})
// 1.獲取
state.foo // ok
// 2.設置已存在屬性
state.foo = 'fooooooo' // ok
// 3.設置不存在屬性
state.dong = 'dong' // ok
// 4.刪除屬性
delete state.dong // ok
嵌套對象響應式

測試:嵌套對象不能響應

// 設置嵌套對象屬性
react.bar.a = 10 // no ok

添加對象類型遞歸

      // 提取幫助方法const isObject = val => val !== null && typeof val === 'object'function reactive (obj) {//判斷是否對象if (!isObject(obj)) {return obj}const observed = new Proxy(obj, {get (target, key, receiver) {// ...// 如果是對象需要遞歸return isObject(res) ? reactive(res) : res},//...}
避免重復代理

重復代理,比如

reactive(data) // 已代理過的純對象
reactive(react) // 代理對象

解決方式:將之前代理結果緩存,get時直接使用

const toProxy = new WeakMap() // 形如obj:observedconst toRaw = new WeakMap() // 形如observed:objfunction reactive (obj) {//...// 查找緩存,避免重復代理if (toProxy.has(obj)) {return toProxy.get(obj)}if (toRaw.has(obj)) {return obj}const observed = new Proxy(...)// 緩存代理結果toProxy.set(obj, observed)toRaw.set(observed, obj)return observed}// 測試效果console.log(reactive(data) === state)console.log(reactive(state) === state)

?原創不易,還希望各位大佬支持一下\textcolor{blue}{原創不易,還希望各位大佬支持一下}

👍 點贊,你的認可是我創作的動力!\textcolor{green}{點贊,你的認可是我創作的動力!}

?? 收藏,你的青睞是我努力的方向!\textcolor{green}{收藏,你的青睞是我努力的方向!}

?? 評論,你的意見是我進步的財富!\textcolor{green}{評論,你的意見是我進步的財富!}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248565.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248565.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248565.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

react Native 環境安裝配置——圖解版一目了然

?原創不易&#xff0c;還希望各位大佬支持一下\textcolor{blue}{原創不易&#xff0c;還希望各位大佬支持一下}原創不易&#xff0c;還希望各位大佬支持一下 &#x1f525; Flutter和reactNative的區別\textcolor{green}{Flutter和react Native的區別}Flutter和reactNative的…

第七章 字典和集合[DDT書本學習 小甲魚]【2】

7.1.2 字典的各種內置方法在序列里為不存在位置賦值&#xff0c;會出現錯誤&#xff1b;而在字典不存在得位置賦值&#xff0c;會創建。工廠函數&#xff08;類型&#xff09;以前學過 str(),int(),list(),tuple()....... 1.fromkeys() 用于創建和返回一個新的字典 不是修改 2…

Installing Node.js and Express on Ubuntu

Installing Node.js and Express on Ubuntu 1. 在nodejs官網上下載Linux Binaries(已經包含了npm):2. 安裝Node.js下載后解壓&#xff0c;并在解壓的文件夾中啟動Terminal后&#xff0c;輸入命令&#xff1a; sudo cp * /usr/local/ -r再輸入命令&#xff1a; node -v …

Chrome插件我只服你——10w人都在使用的瀏覽器插件

?文章摘要導讀\textcolor{blue}{文章摘要導讀}文章摘要導讀 &#x1f525; 為什么選擇Chrome插件\textcolor{green}{為什么選擇Chrome插件}為什么選擇Chrome插件 &#x1f525; 插件具備的強大優勢\textcolor{green}{插件具備的強大優勢}插件具備的強大優勢 &#x1f525; …

H3C通過端口ID決定端口角色

轉載于:https://www.cnblogs.com/fanweisheng/p/11153312.html

特殊屬性

轉載于:https://www.cnblogs.com/mengbin0546/p/10338371.html

一款超強的手機屏幕投影工具

?文章摘要導讀\textcolor{blue}{文章摘要導讀}文章摘要導讀 &#x1f525; 前言\textcolor{green}{前言}前言 &#x1f525; 準備工作\textcolor{green}{準備工作}準備工作 &#x1f525; Scrcpy安裝\textcolor{green}{Scrcpy安裝}Scrcpy安裝 &#x1f525; 工具調試\text…

長度不超過n的連續最大和___優先隊列

題目鏈接: https://nanti.jisuanke.com/t/36116 題目: 在蒜廠年會上有一個抽獎&#xff0c;在一個環形的桌子上&#xff0c;有 nn 個紙團&#xff0c;每個紙團上寫一個數字&#xff0c;表示你可以獲得多少蒜幣。但是這個游戲比較坑&#xff0c;里面竟然有負數&#xff0c;表示你…

JS一維數組轉化為三維數組有這個方法就夠了

今天在CSDN上問答區看到一個提問的小伙伴&#xff0c;是想要將一維數組轉化為三位數組的需求&#xff0c;正好不是很忙&#xff0c;樂于助人的我立馬給這位同學安排上 下面是后端同學返給我們的一維數組數據格式 [{品牌: xiaomi, 機型: 10, 配置: 512},{品牌: xiaomi, 機型: 10…

Hadoop集群安裝

一、完全分布式模式的安裝和配置的具體步驟&#xff1a; 1.配置jdk&#xff1b;2.配置hosts文件&#xff1b;3.建立hadoop運行賬號&#xff1b;4.配置ssh免密碼連入&#xff1b; 5.下載并解壓hadoop安裝包&#xff1b;6.配置namenode&#xff0c;修改site文件&#xff1b;7.配置…

11系列

夢想這東西和經典一樣 永遠不會隨時間而褪色 反而更顯珍貴轉載于:https://www.cnblogs.com/tianjinquan/archive/2010/11/03/1867694.html

webpack相關配置

文章目錄&#x1f4a6; webpack的概念&#x1f4a6; webpack的基本使用項目目錄并初始化創建首頁及js文件以jQuery為例安裝jQuery導入jQuery安裝webpack&#x1f4a6; webpack的相關設置設置webpack的打包入口/出口設置webpack的自動打包配置html-webpack-pluginwebpack中的加載…

Day 21 20190205 老男孩python學習第21天 內容整理

今天寫作業&#xff0c;明天后天要在外旅游 寫作業寫了7個小時。 1 def read_file_as_dict(where):2 staff_dict {}3 f open(%s % where, mode"r", encodingutf-8)4 data f.read()5 f.close()6 row data.strip().split(\n)7 for staff i…

SCOM 簡單界面操作指南 [SCOM中文系列之三]

今天大概介紹下SCOM的管理界面&#xff0c;大概分三個重要的功能版塊 Monitoring 監控版面 Authoring &#xff08;中文版不知道翻譯成什么&#xff0c;主要編輯MP&#xff09; Administration 管理操作 首先說一下管理操作區&#xff0c;開始裝好的SCOM都需要來這里配置一下的…

趁著對象泡腳的功夫,我把vueX吃透了

文章目錄vueX&#x1f31f;Vuex的概述什么是vuexVuex管理數據的優點&#x1f31f;Vuex的基本使用步驟1.安裝 npm i vuex --save2.在src文件目錄下新建store>index.js文件3.口文件里面引入store&#xff0c;然后再全局注入4.使用&#x1f31f;Vuex中的核心特性State在組件中訪…

【題解】FBI序列

題目描述 兩伙外星人策劃在未來的XXXX年侵略地球&#xff0c;侵略前自然要交換信息咯&#xff0c;現在&#xff0c;作為全球保衛隊隊長&#xff0c;你截獲了外星人用來交換信息的一段僅由“F”&#xff0c;“B”&#xff0c;“I”&#xff0c;“O”組成的序列。為了保衛地球和平…

vue基礎(上篇)

?有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于vue的基礎篇\textcolor{blue}{ 有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于 vue的基礎篇}有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于vue的基礎篇 ? 今天他來了…

depends用于測試程序運行所缺少的文件,可以幫我們很快找到問題

DEPENDS工具和DUMPBIN工具使用閱讀目錄(Content) 1.Depends2.DUMPBIN2.1 開啟CMD2.2 移動目錄到C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin2.3 運行命令:VCVARS32.BAT2.4 下面就可以調用dumpbin.exe命令了在系統部署運行時我們經常發現某個程序在開發機器中可以…

友聯

歡迎來到小站友鏈區&#xff0c;歡迎━(&#xff40;?)ノ亻!。 ljc20020730學長巨佬_WA自動機珂朵莉最可愛了BLUESKY007雷姆最可愛啦揚子曰他的代碼是神奇的lukelin機房最強如果你想要成為chhokmah小站的朋友的話&#xff0c;請你先把小站加入為友鏈站喲(&#xff3e;&#xf…

vue基礎(中篇)

?有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于vue的基礎篇\textcolor{blue}{ 有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于 vue的基礎篇}有粉絲在私信中聯系博主&#xff0c;希望博主能夠系統的出一篇關于vue的基礎篇 ? 今天他來了…