VUE2雙向綁定的原理

文章目錄

  • VUE2雙向綁定的原理
  • 1. 什么是雙向綁定
  • 2. 雙向綁定的原理
    • 2.1 ViewModel的重要作用
    • 2.2 雙向綁定的流程
  • 3. 雙向綁定的實現
    • 3.1 data響應化處理
    • 3.2 Compile編譯
    • 3.3 依賴收集

VUE2雙向綁定的原理

1. 什么是雙向綁定

  • 講雙向綁定先講單項綁定,啥叫單項綁定,就是一句話就是通過Model去改變View,再直白點,就是通過js代碼把數據改變后,html視圖也跟著變化
  • 那雙項綁定就很好理解了,在單項綁定的基礎上,如果view改變了,Model也能同步變化
  • 一句話概括就是,Model變化View跟著跟新,View跟新,Model跟著變化,這就是雙向綁定

2. 雙向綁定的原理

  • 其實我們可以很容易想到一點就是,如果A變化了想要B跟著變化,最簡單的方式就是,A變化的時候通知一下B就行,這就是基本思路
  • 在VUE2 中,雙向綁定由三個重要部分構成
  1. 數據層(Model),應用的數據及業務邏輯
  2. 視圖層(View),應用的展示效果,理解為UI組件
  3. 業務邏輯層(ViewModel),框架封裝的核心,他主要負責把數據層和視圖層關聯起來,這就是MVVM模型

2.1 ViewModel的重要作用

  • ViewModel主要干兩件事
  1. 數據變化后,更新視圖
  2. 視圖變化后,更新數據
  • 那么問題來了,怎么通知呢,我們怎么知道數據變化后,通知哪些視圖呢
  • 這要依賴ViewModel的兩個重要部件
  1. 監聽器(Observer),對所有數據的屬性進行監聽
  2. 解析器(Compiler),對元素節點的指令進行掃描跟解析,根據指令模板替換數據,以及綁定相應的更新函數

2.2 雙向綁定的流程

  • 雙向綁定的流程
  1. 我們在new Vue()時,執行初始化,對data執行相應化處理,這個過程發生在Observer中
  2. 同時對模板執行編譯,找到其中動態綁定的數據,從data中獲取并初始化視圖,這個過程發生在Compiler中
  3. 同時定義一個更新函數和Watcher,將來對應數據變化時,Watcher會調用更新函數
  4. 由于data中的數據的某個key可能出現在視圖的多處,所以每個key都需要一個管家Dep來管理多個Watcher
  5. 將來數據一旦發生變化,會首先找到對應的Dep,通過Dep李曼的所有Watcher執行更新函數
    在這里插入圖片描述

3. 雙向綁定的實現

3.1 data響應化處理

  • 我們來創建一個構造函數,執行初始化,對data數據執行響應化處理
class Vue{constrcutor(options){this.$options=options;this.$data=options.data;//對data選項做響應式處理Observe(this.$data)//代理data到vm上proxy(this)// 執行編譯new Compile(options.el,this)}
}
function Observe(obj){if(typeof obj!=='object' || obj===null){return;}new Observer(obj)
}
class Observer{constructor(value){this.value=value;this.walk(value)}walk(obj){Object.keys(obj).forEach((key)=>{defineReactive(obj,key,obj[key])//內部是Object.defineProperty實現,后面會講})}
}

3.2 Compile編譯

  • 對元素節點的指令機型掃描跟解析,根據指令模板替換數據,以及綁定相應的更新函數
class Compile{constructor(el,vm){this.$vm=vm;this.$el=document.querySelector(el);//獲取DOMif(this.$el)this.compile(this.#el)}compile(el){const childNodes=el.ChildNodes;Array.from(childNodes).forEach((node)=>{//遍歷子元素if(this.isElement(node)){//判斷是否為節點/*編譯元素*/}else if(this.inInterpolation(node)){//是否為差值文本/*編譯差值文本*/}if(node.childNodes && node.childNodes.length>0){this.compile(node)}})}isElement(node){return node.nodeType===1}isInterpolation(node){return node.nodeType===3 && /\{\{(.*)\}\}/.test(node.textContent)}
}

3.3 依賴收集

  • 視圖中會用到data中的某個key,這被稱為依賴,一個key可能出現在視圖中的多個位置,每次都需要收集出來用一個Watcher來維護他們,這個過程被稱為依賴收集,很多歌Watcher需要一個Dep來管理,需要更新時由Dep統一通知
    在這里插入圖片描述

  • 基本思路

  1. defineReactive為每一個key創建一個Dep,比如data1創建Dep1
  2. 初始化視圖時,讀取某個key,例如data1,就創建一個watcher1
  3. 由于讀取key時觸發getter方法,邊疆watcher1天假到data1的Dep1中份
  4. 當data1更新時,觸發setter,通過Dep1通知所有的watcher更新
class Wacther{constructor(vm,key,updater){this.$vm=vm;this.$key=key;this.updaterFn=updater;//創建實例時,把當前實例指定到Dep.target靜態屬性上Dep.target=this;vm[key]//讀一下key,觸發getDep.target=nullupdate(){this.updaterFn.call(this.$vm,this.$vm[this.$key])}}
}
class Dep{constructor(){this.deps=[];//依賴管理 }addDep(dep){this.deps.push(dep)}notify(){this.deps.forEach((dep)=>{dep.update()})}
}
// 創建Watcher時觸發getter
function defineReactive(obj,key,val){this.observe(val)const dep=new Dep()Object.defineProperty(obj,key,{get (){Dep.target && dep.addDep(Dep.target)//Dep.target就是Watcher實例return val},set(newVal){if(newVal===val)returndep.notify()//通知dep執行更新方法  }})
}

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

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

相關文章

4G核心網的演變與創新:從傳統到虛擬化的跨越

4G核心網 隨著移動通信技術的不斷發展,4G核心網已經經歷了從傳統的硬件密集型架構到現代化、虛擬化網絡架構的重大轉型。這一演變不僅提升了網絡的靈活性和可擴展性,也為未來的5G、物聯網(LOT)和邊緣計算等技術的發展奠定了基礎。…

云計算——AWS Solutions Architect – Associate(saa)1、什么是云,AWS介紹

什么是云? 什么是云? 云計算(cloud computing)是基于互聯網的相關服務的增加、使用和交付模式,通常涉及通過互聯網來提供動態易護展且經常是虛擬化的資源。云是網絡、互聯網的一種比喻說法。 簡單理解為:云是 共享資源,按需付費&#xff0…

HTML排版標簽、語義化標簽、塊級和行內元素詳解

目錄 前言 一、HTML中的排版標簽 1. 文本相關標簽 1.1 標題標簽 ~ 1.2 段落標簽 1.3 強調和加粗 1.4 換行標簽 1.5 水平線標簽 二、HTML中的語義化標簽 2.1 語義化標簽概述 2.2 常見的語義化標簽 示例(核心代碼部分): 三、HTM…

【字節青訓營-7】:初探 Kitex 字節微服務框架(使用ETCD進行服務注冊與發現)

本文目錄 一、Kitex概述二、第一個Kitex應用三、IDL四、服務注冊與發現 一、Kitex概述 長話短說,就是字節跳動內部的 Golang 微服務 RPC 框架,具有高性能、強可擴展的特點,在字節內部已廣泛使用。 如果對微服務性能有要求,又希望…

【數學】矩陣、向量(內含矩陣乘法C++)

目錄 一、前置知識:向量(一列或一行的矩陣)、矩陣1. 行向量2. 列向量3. 向量其余基本概念4. 矩陣基本概念5. 關于它們的細節 二、運算1. 轉置(1)定義(2)性質 2. 矩陣(向量&#xff0…

TCP/IP 郵件

TCP/IP 郵件 引言 在互聯網技術飛速發展的今天,電子郵件(Email)已成為人們日常工作和生活中不可或缺的通信工具。TCP/IP協議作為互聯網通信的基礎,為電子郵件的傳輸提供了強大的技術支持。本文將詳細介紹TCP/IP在電子郵件傳輸過程中的作用,以及相關的協議和實現方式。 …

離線安裝Appium Server

1、問題概述? 安裝Appium通常有兩種方式: 第一種:下載exe安裝包,這種是Appium Server GUI安裝方式,缺點是通過命令啟動不方便。 第二種:通過cmd安裝appium server,可以通過命令方式啟動,比較方便。 問題:在沒有外網的情況下,無法通過命令在cmd中安裝appium server…

設計模式六大原則和單例模式

設計模式 目的 實現可重用解決方案,構筑易維護、可擴展的軟件系統。 六大原則 單一職責: 類的職責單一,一個方法做一件事。 開閉原則: 拓展開放,修改關閉。 里氏替換: 父類能出現的地方,子…

淺嘗yolo11全程記錄1-準備環境+官網模型推理(個人備份)

準備工作(虛擬環境、導入項目) 安裝Anaconda 主要是為了創建和管理虛擬環境,在pycharm里按照項目里的requirments.txt安裝依賴的時候,使用虛擬環境會好很多(我記得不用Anaconda也可以直接在pycharm的terminal里頭創建…

5.攻防世界 fileinclude

進入題目頁面如下 提示flag在flag.php ctrlu&#xff0c;查看源碼 給出了一段PHP代碼&#xff0c;進行代碼審計 <?php // 檢查是否開啟了錯誤顯示功能 if( !ini_get(display_errors) ) {// 如果沒有開啟&#xff0c;則將錯誤顯示功能設置為開啟狀態ini_set(display_error…

深入淺出 NRM:加速你的 npm 包管理之旅

文章目錄 前言一、NRM 是什么&#xff1f;二、為什么需要 NRM&#xff1f;三、NRM 的優勢四、NRM 的安裝與使用4.1 安裝 NRM4.2 查看可用的 npm 源4.3 切換 npm 源4.4 測試 npm 源速度4.5 添加自定義 npm 源4.6 刪除 npm 源 五、NRM 的進階使用六、總結 前言 作為一名 JavaScr…

《C#之集訓1-20121019c#基礎》

&#xfeff;&#xfeff; C#是微軟公司發布的一種面向對象的、運行于.NET Framework之上的高級程序設計語言。它是微軟公司研究員Anders Hejlsberg的最新成果。 C#曾經的它在我眼中是很高大上的&#xff0c;一直沒有目睹其風采&#xff0c;現在終于揭開了它神秘的面紗&#xf…

紅包雨項目前端部分

創建項目 pnpm i -g vue/cli vue create red_pakage pnpm i sass sass-locader -D pnpm i --save normalize.css pnpm i --save-dev postcss-px-to-viewportpnpm i vantlatest-v2 -S pnpm i babel-plugin-import -Dhttps://vant.pro/vant/v2/#/zh-CN/<van-button click&…

藍橋杯嵌入式備賽(三)—— LED +按鍵 + LCD

目錄 一、LED1、原理圖介紹2、程序代碼 二、按鍵1、原理圖介紹2、程序代碼 三、LCD1、原理圖介紹2、程序代碼 一、LED 1、原理圖介紹 如果所示&#xff0c;STM32G431RBT6中有八個LED&#xff0c;由八個GPIO控制&#xff0c;分別為PC8-15&#xff0c;當輸出為低電平時點亮。其中…

深入剖析 HTML5 新特性:語義化標簽和表單控件完全指南

系列文章目錄 01-從零開始學 HTML&#xff1a;構建網頁的基本框架與技巧 02-HTML常見文本標簽解析&#xff1a;從基礎到進階的全面指南 03-HTML從入門到精通&#xff1a;鏈接與圖像標簽全解析 04-HTML 列表標簽全解析&#xff1a;無序與有序列表的深度應用 05-HTML表格標簽全面…

[Java基礎]函數式編程

Lambda函數 JDK8新增的語法形式, 使用Lambda函數替代某些匿名內部類對象&#xff0c;從而讓程序代碼更簡潔&#xff0c;可讀性更好。 基本使用 lambda表達式只能簡化函數式接口的匿名內部類寫法 // 1.定義抽象類 abstract class Animal {public abstract void crt(); }publi…

Vue通過觸發與監聽事件進行數據傳遞: 子組件調用 $emit 方法來將數據傳遞給父組件。

文章目錄 引言I 組件事件事件參數defineEmits 宏聲明需要拋出的事件事件校驗例子:子組件告訴父組件放大所有博客文章的文字II 【詳細說明】 子組件通過觸發一個事件,將數據傳遞給父組件調用內建的 `$emit `方法傳入事件名稱來觸發一個事件子組件通過`this.$emit`來觸發一個事…

Vim 多窗口編輯及文件對比

水平分割 :split 默認使用水平分割的方式。 :split :sp 垂直分割 :vsplit :vs 帶文件的分割 :split 文件名 :sp 文件名 在光標所在的窗口&#xff0c;輸入分割窗口命令就會對那個窗口進行分割。 切換窗口 Ctrlw 切換正在編輯的窗口 快速分割窗口 Ctrlwn 快速分割當前…

“衛星-無人機-地面”遙感數據快速使用及地物含量計算的實現方法

在與上千學員交流過程中&#xff0c;發現科研、生產和應用多源遙感數據時&#xff0c;能快速上手&#xff0c;發揮數據的時效性&#xff0c;盡快出創新性成果&#xff0c;是目前的學員最迫切的需求。特別是按照“遙感數據獲取-處理-分析-計算-制圖”全流程的答疑解惑&#xff0…

二級C語言題解:十進制轉其他進制、非素數求和、重復數統計

目錄 一、程序填空&#x1f4dd; --- 十進制轉其他進制 題目&#x1f4c3; 分析&#x1f9d0; 二、程序修改&#x1f6e0;? --- 非素數求和 題目&#x1f4c3; 分析&#x1f9d0; 三、程序設計&#x1f4bb; --- 重復數統計 題目&#x1f4c3; 分析&#x1f9d0; 前言…