vue2和vue3響應式原理模擬


准備工作

         1.數據驅動

         2.響應式核心原理

         3.發布訂閱模式和觀者者模式

 1.數據驅動

  • 數據響應式、雙向綁定、數據驅動
  • 數據響應式
  1. 數據模型僅僅是普通的javaScript對象,而當我們修改數據的時候,視圖會進行更新,避免了繁瑣的DOM操作,提高工作效率
  • 雙向綁定
  1.  數據改變,視圖改變,視圖改變,數據也會隨之改變
  2. 我們可以使用v-model在表單元素上創建雙向數據綁定
  • 數據驅動時vue最獨特的特性之一

   1.開發過程中僅需要關注數據本身,不需要關心數據是如何渲染到視圖的

vue響應式原理 ---核心方法 Object.defineProperty()

一段代碼模擬演示一下

<div id="app">
      hello
</div>
//模擬vue中的data選項
let data ={ msg:'hello', count:0 }
//模擬vue實例 let vm ={}
//數據劫持:當訪問或者設置vm的成員的時候,做一些干預操作 Object.defineProperty(vm,'msg',{ enumerable:true, //可枚舉 configurable:true, //可配置(可以通過delete刪除,可以通過defineProperty重新定義)
   //當獲取值得時候執行 get(){ console.log('get',data.msg) return data.msg },
//當設置值得時候執行 set(newValue){ console.log('set',newValue) if(newValue === data.msg){ return } data.msg=newValue
//數據更改 更新Dom的值 document.querySelector('#app').textContent =data.msg } })

測試:

   vm.msg=‘hello world'

   console.log('vm',vm.msg)

結果:當我們設置值的時候出發了set方法  打印值得時候觸發了get方法

 

如果有一個對象中多個屬性需要轉化getter和setter如何處理?

上面只是轉換了msg屬性

//模擬vue中的data選項
let data ={ msg:'hello', count:0 }
//模擬vue實例 let vm ={}
//數據劫持:當訪問或者設置vm的成員的時候,做一些干預操作
proxyData(data)
//遍歷data中的所有屬性 function proxyData(data){ Object.keys(data).forEach(key =>{
把data中的屬性轉換成vm的setter和getter Object.defineProperty(vm,key,{ enumerable:true, configurable:true, get(){ console.log('get:',key,data[key]) return data[key] }, set(newValue){ console.log('set',key,newValue) if(newValue == data[key]){ return } data[key]=newValue document.querySelector('#app').textContent = data[key] } }) }) }
測試: 
vm.msg ='hello world'
vm.count ='1'
console.log(vm.msg,vm.count)
結果:

 

 這樣就實現了多屬性的響應式

以上是vue2的響應式原理,接下來我們可以一起看一下vue3的數據響應式原理

let vm = new Proxy(data, {
//執行代理行為的函數
//當訪問vm的成員執行
// 我們要代理的對象data就是這個:target參數,key:訪問得哪個屬性 這兩個屬性怎么傳過來的我們無需關心 get(target, key) { console.log('get', key, target[key]) return target[key] }, set(target, key, newValue) { console.log('set', key, newValue) if (target[key] === newValue) { return } target[key] = newValue document.querySelector('#app').textContent = target[key] } })

  

測試: 
vm.msg ='hello world'
vm.count ='1'
console.log(vm.msg,vm.count)
結果:

 

 

 

 

 



 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM