深入Vue原理_全面剖析發布訂閱模式

文章目錄

    • 發布訂閱模式優化
      • 優化思路思考
      • 理解發布訂閱模式(自定義事件)
      • 收集更新函數
      • 觸發更新函數
      • 6.5 總結
    • 總結
    • 寫在最后
    • 本期推薦

歡迎各位小伙伴們!
為大家推薦一款刷題神奇哦 點擊鏈接訪問牛客網
各大互聯網大廠面試真題。從基礎到入階乃至原理刨析類面試題 應有盡有,趕快來裝備自己吧!助你面試穩操勝券,solo全場面試官
上節中我們提到下方更新的問題:無法做到精準更新

<div id="app"><p v-text="name"></p><p v-text="age"></p><p v-text="name"></p>
</div>
<script>let data = {name: '小蘭同學',age: 18,height: 180}// 遍歷每一個屬性Object.keys(data).forEach((key) => {// key 屬性名// data[key] 屬性值// data 原對象defineReactive(data, key, data[key])})function defineReactive(data, key, value) {Object.defineProperty(data, key, {get() {return value},set(newVal) {// 數據發生變化,操作dom進行更新if (newVal === value) {return}value = newValcompile()}})}// 編譯函數function compile() {let app = document.getElementById('app')// 1.拿到app下所有的子元素const nodes = app.childNodes   //  [text, input, text]//2.遍歷所有的子元素nodes.forEach(node => {// nodeType為1為元素節點if (node.nodeType === 1) {const attrs = node.attributesArray.from(attrs).forEach(attr => {const dirName = attr.nodeNameconst dataProp = attr.nodeValueconsole.log( dirName,dataProp)if (dirName === 'v-text') {console.log(`更新了${dirName}指令,需要更新的屬性為${dataProp}`)node.innerText = data[dataProp]}})}})}// 首次渲染compile()
</script>

發布訂閱模式優化

優化思路思考

1.數據更新之后實際上需要執行的代碼是什么?

node.innerText = data[dataProp]

為了保存當前的node和dataProp,我們再次設計一個函數執行利用閉包函數將每一次編譯函數執行時候的node和dataProp都緩存下來,所以每一次數據變化之后執行的是這樣的一個更新函數

() => {node.innerText = data[dataProp]
}

2.一個響應式數據可能會有多個視圖部分都需要依賴,也就是響應式數據變化之后,需要執行的更新函數可能不止一個,如下面的代碼所示,name屬性有倆個div元素都使用了它,所以當name變化之后,倆個div節點都需要得到更新,那屬性和更新函數之間應該是一個一對多的關系

<div id="app"><div v-text="name"></div><div v-text="name"></div><p v-text="age"></p><p v-text="age"></p>
</div><script>let data = {name: 'cp',age: 18}
</script>

經過分析我們可以得到下面的存儲架構圖,每一個響應式屬性都綁定了相對應的更新函數,是一個一對多的關系,數據發生變化之后,只會再次執行和自己綁定的更新函數

在這里插入圖片描述

理解發布訂閱模式(自定義事件)

理解發布訂閱,關鍵是理解一對多

1. 從瀏覽器事件說起

dom綁定事件的方式,我們學過倆種

  1. dom.onclick = function(){}
  2. dom.addEventListener(‘click’,()=>{})

這倆種綁定方式的區別是,第二種方案可以實現同一個事件綁定多個回調函數,很明顯這是一個一對多的場景,既然瀏覽器也叫作事件,我們試著分析下瀏覽器事件綁定實現的思路

  1. 首先addEventListenr是一個函數方法,接受倆個參數,分別是事件類型回調函數

  2. 因為是一個事件綁定多個回調函數,那在內存里大概會有這樣的一個數據結構

    {click: ['cb1','cb2',....],input: ['cb1','cb2',...]
    }
    
  3. 觸發事件執行,瀏覽器因為有鼠標鍵盤輸入可以觸發事件,大概的思路是通過事件名稱找到與之關聯的回調函數列表,然后遍歷執行一遍即可

ok,我們分析了瀏覽器事件的底層實現思路,那我們完全可以自己模仿一個出來,事件的觸發,我們也通過設計一個方法來執行

2. 實現簡單的發布訂閱

// 增加dep對象 用來收集依賴和觸發依賴
const dep = {map: Object.create(null),// 收集collect(dataProp, updateFn) {if (!this.map[dataProp]) {this.map[dataProp] = []}this.map[dataProp].push(updateFn)},// 觸發trigger(dataProp) {this.map[dataProp] && this.map[dataProp].forEach(updateFn => {updateFn()})}
}

收集更新函數

在編譯函數執行的時候,我們把用于更新dom的更新函數收集起來

 // 編譯函數function compile() {let app = document.getElementById('app')// 1.拿到app下所有的子元素const nodes = app.childNodes   //  [text, input, text]//2.遍歷所有的子元素nodes.forEach(node => {// nodeType為1為元素節點if (node.nodeType === 1) {const attrs = node.attributes// 遍歷所有的attrubites找到 v-modelArray.from(attrs).forEach(attr => {const dirName = attr.nodeNameconst dataProp = attr.nodeValueconsole.log(dirName, dataProp)if (dirName === 'v-text') {console.log(`更新了${dirName}指令,需要更新的屬性為${dataProp}`)node.innerText = data[dataProp]// 收集更新函數dep.collect(dataProp, () => {node.innerText = data[dataProp]})}})}})}

觸發更新函數

當屬性發生變化的時候,我們通過屬性找到對應的更新函數列表,然后依次執行即可

function defineReactive(data, key, value) {Object.defineProperty(data, key, {get() {return value},set(newValue) {// 更新視圖if (newValue === value) returnvalue = newValue// 再次編譯要放到新值已經變化之后只更新當前的keydep.trigger(key)}})
}

6.5 總結

  1. 了解了發布訂閱模式的基礎形態
  2. 了解發布訂閱可以解決什么樣的具體問題(精準更新)

總結

  1. 數據響應式的實現無非是對象屬性攔截,我們使用Object.defineProperty來實現,在vue3中使用Proxy對象代理方案進行了優化,解決了Object.defineProperty存在的缺陷

  2. observe對象指的是把數據處理成響應式的對象

    watcher指的其實就是數據變化之后的更新函數 (Vue中的watcher有兩種,一種是用來更新視圖的watcher,一種是通過watch配置項聲明的watcher)

    dep指的就是使用發布訂閱實現的收集更新函數和觸發更新函數的對象

  3. 指令實現的核心無非是通過模板編譯找到標識然后把數據綁上去,等到數據變化之后再重新放一次

  4. 發布訂閱模式的本質是解決一對多的問題,在vue中實現數據變化之后的精準更新

寫在最后

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

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

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

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

本期推薦

在這里插入圖片描述

【內容簡介】
  本書以理論結合編程開發為原則,使用Python作為開發語言,講解化算法的原理和應用,詳細介紹了Python基礎、Gurobi 優化器、線性規劃、整數規劃、多目標優化、動態規劃、圖與網絡分析、智能優化算法。對于算法部分的每一種算法都包含原理和編程實踐,使讀者對化算法的認識更加深入。
 
  本書分為 3 篇共 9 章。第 1 篇(第 1~3 章)是化算法與編程基礎:第 1 章介紹了什么是化算法及其在生產和生活中的應用;第 2章介紹Python編程基礎和Python數據分析庫及繪圖庫;第 3章講解Gurobi 優化器的基礎和高級特性。第 2篇(第 4~6章)是數學規劃方法:第 4章詳細講解線性規劃的知識,包括單純形法、內點法、列生成法、拉格朗日乘子法、對偶問題;第 5 章講解整數規劃解法的分支定界法和割平面法;第 6 章講解多目標優化的概念及基于單純形法的目標規劃法。第 3 篇(第 7~9 章)是啟發式算法:第 7 章介紹動態規劃算法;第 8 章講解圖與網絡分析,介紹*小生成樹、短路徑、網絡流、路徑規劃等問題的建模;第 9 章講解了粒子群算法和遺傳算法求解各種類型優化算法問題的方法。
  本書內容豐富,實例典型,實用性強,適合各個層次從事
化算法研究和應用的人員,尤其適合有一定算法基礎而沒有編程基礎的人員閱讀。

【作者簡介】
  蘇振裕,廈門大學金融學碩士,現任SHEIN 智慧供應鏈資深算法工程師。知乎專欄《從推公式到寫代碼》作者,運籌優化論壇(optimize.fun)創建人。在大數據、人工智能、運籌優化和供應鏈方面,具有多年的相關算法研究應用經驗。

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

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

相關文章

前端面試系列-JS 異步編程

并發與并行的區別&#xff1f; 并發是宏觀概念&#xff0c;我分別有任務 A 和任務 B&#xff0c;在一段時間內通過任務間的切換完成了這兩個任務&#xff0c;這種情況就可以稱之為并發。并行是微觀概念&#xff0c;假設 CPU 中存在兩個核心&#xff0c;那么我就可以同時完成任務…

web前端發展歷程

總覽前端發展史前言瀏覽器的發展史走進前端HTMLCSSjavaScript小前端時代大前端時代寫在最后前言 目前在IT公司中前端的崗位越來越成為不可或缺的&#xff0c;前端的地位也愈見明顯&#xff0c;很多學校已經體系的傳授前端課程&#xff0c;眾多培訓機構也將前端知識作為了主流課…

修改wordpress上傳文件大小限制

1. 登陸wordpress使用的數據庫&#xff0c;切換到使用的database 2. 操作如下&#xff1a; > select meta_key from wp_sitemeta; > select meta_key,meta_value from wp_sitemeta where meta_keyfileupload_maxk; 修改為20M: > update wp_sitemeta set meta_value204…

php的符號的排序大小

轉載于:https://www.cnblogs.com/cjjjj/p/10433334.html

淺談 HTTP 和 HTTPS

很多前端伙伴問題有沒有體系的面試題&#xff1f; 今天為大家推薦一款刷題神奇哦 點擊鏈接訪問牛客網 各大互聯網大廠面試真題。從基礎到入階乃至原理刨析類面試題 應有盡有&#xff0c;趕快來裝備自己吧&#xff01;助你面試穩操勝券&#xff0c;solo全場面試官 淺談 HTTP 和 …

Ubuntu 搭建 GitLab 筆記 ***

簡介 GitLab 社區版可以提供許多與 GitHub 相同的功能&#xff0c;且部署在屬于自己的機器上&#xff0c;我們會因為網絡及其他一些問題而不便使用 GitHub &#xff0c;這時部署一個 GitLab 是最好的選擇。 下載 GitLab 并安裝 我的環境是 Ubuntu 16.04 下進行部署操作。 GitLa…

在瀏覽器輸入URL到頁面展示發生了什么?

輸入URL后查詢緩存DNS服務器TCP三次握手HTTP協議包瀏覽器處理HTML文檔TCP 和 UDP 的區別寫在最后很多前端伙伴問題有沒有體系的面試題&#xff1f; 今天為大家推薦一款刷題神奇哦 點擊鏈接訪問牛客網 各大互聯網大廠面試真題。從基礎到入階乃至原理刨析類面試題 應有盡有&#…

iOS 高級去水印,涂鴉去水印

目前在研究一下圖像的處理&#xff0c;看了一下相關的軟件&#xff0c;比如&#xff1a;《去水印大師》&#xff0c;究竟去水印是怎么處理的呢&#xff1f;看圖分析。 一共是三個功能&#xff1a;快速去水印、高級去水印、涂鴉去水印 快速去水印&#xff1a;暫時沒找到好的處理…

Failed to execute goal maven-gpg-plugin 1.5 Sign

問題描述&#xff1a; 解決辦法&#xff1a;跳過maven-gpg-plugin <build> <pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-gpg-plugin</artifactId><configuration&g…

打造硬核敲門磚——簡歷

文章目錄 前言打造簡歷篇幅模板個人信息專業技能工作經歷項目經歷教育經歷個人總結簡歷格式寫在最后前言 作為高校的學生,你是否已經開始設想你以后的工作?作為職場的員工,你是否已經準備更換下一份工作了?不論你現在是什么身份、處于什么階段,這篇文章都能夠幫到你,只要…

Robot Framework 內置變量

Robot Framework 內置變量 轉自&#xff1a;https://blog.csdn.net/qq_26886929/article/details/53907755 Robot Framework 內部提供了一下直接可用的內置變量 1. 操作系統相關變量 內置的操作系統相關的變量&#xff0c;減少了測試數據對操作系統之間的差異性的關注 RF 中可用…

一文搞懂this指向

前言 那你說一下 js 中的 this 指向吧&#xff01;這句話已經成為面試官口中的高頻面試題&#xff0c;作為前端開發的我們&#xff0c;你真的搞懂了 this 指向了嗎&#xff1f;快來跟我一起來查漏補缺吧&#xff01;通過幾個小案例讓大家更能直白的理解 this 指向。 很多前端伙…

難怪大家丟掉了postman而選擇 Apifox

前言 當下采用前后端分離模式開發Web應用已經成為氣候&#xff0c;在開發階段有一個不成文的規定則是 項目開發后端先行 但是作為前端開發工程師的我們&#xff0c;難道在搭建完頁面后只能等待后端的接口么&#xff1f;這樣的話我們則完全被后端開發限制住了。在前面跟大家介紹…

mvc 模式和mtc 模式的區別

首先說說Web服務器開發領域里著名的MVC模式&#xff0c;所謂MVC就是把Web應用分為模型(M)&#xff0c;控制器(C)和視圖(V)三層&#xff0c;他們之間以一種插件式的、松耦合的方式連接在一起&#xff0c;模型負責業務對象與數據庫的映射(ORM)&#xff0c;視圖負責與用戶的交互(頁…

HP LaserJet MFP M227_M231雙面打印

雙面打印設置 轉載于:https://www.cnblogs.com/xiexiaokui/p/9261577.html

萬木成林,我種了“Vue技能樹”

初衷 作為Vue技能樹的構建者&#xff0c;一直拖延到現在才來寫這篇文章&#xff0c;主要還是心里沒有底&#xff0c;前面殊不知這顆“樹”是否促進了大家學習的熱情&#xff0c;也不知它給大家帶來了多少收獲。說到我們的Vue技能樹&#xff0c;我作為尤大大的忠實粉絲自就業后…

我看面向對象

已經面向對象編程多年了&#xff0c;漸漸地對面向對象有了越來越深的體會&#xff0c;下面談談我對面向對象的拙見&#xff1a;&#xff09; 面向對象三大特性&#xff1a;封裝、繼承、多態。 首先是封裝&#xff0c;我覺得封裝是面向對象的基礎&#xff0c;封裝讓各種相關的數…

poj 3525

多邊形內最大半徑圓。 哇沒有枉費了我自閉了這么些天&#xff0c;大概五天前我看到這種題可能毫無思路抓耳撓腮舉手投降什么的&#xff0c;現在已經能1A了哇。 還是先玩一會計算幾何&#xff0c;刷個幾百道 嗯這個半平面交二分就闊以解決。雖然隊友說他施展三分套三分***** 想象…

尤雨溪對 2022 Web前端生態趨勢是這樣看的

文章目錄前言開發范式&底層框架方面趨勢基于依賴追蹤范式基于依賴追蹤范式—共同點基于編譯的響應式系統統一模型的優勢和代價基于編譯的運行是優化Vue Vapor Mode&#xff08;input&#xff09;工具鏈原生語言在前端工具鏈中的使用工具鏈的抽象層次基于 Vite 的上層框架上…

bzoj4919 [Lydsy1706月賽]大根堆

Description 給定一棵n個節點的有根樹&#xff0c;編號依次為1到n&#xff0c;其中1號點為根節點。每個點有一個權值v_i。你需要將這棵樹轉化成一個大根堆。確切地說&#xff0c;你需要選擇盡可能多的節點&#xff0c;滿足大根堆的性質&#xff1a;對于任意兩個點i,j&#xff0…