Vue3-Vue2實現數據響應式的區別

Vue2實現響應式的核心:數組

  • 對象:經過defineProperty對對象的已有屬性值的讀取和修改進行劫持(監視/攔截)
  • 數組:經過重寫數組更新數組一系列更新元素的方法來實現元素修改的劫持

一、使用observe函數遍歷data的每一個屬性dom

image.png
二、調用Object.defineProperty()對每一個屬性作響應式處理:利用攔截器屬性get()和set()方法作訂閱-發佈處理。函數

image.png

三、當對一個屬性進行響應式處理的適合,會實例化一個Dep實例,並將用到這個屬性的組件所對應的Watcher實例所有存放在subs數組裏,當屬性被修改時,通知watcher,調用裏面的render函數,進行dom的diff和更新。
image.pngspa

問題:代理

  • 須要遍歷須要監聽的每一個對象的每一個屬性,對其添加definePropert方法,經過其內部的get()和set()方法進行數據的監聽和攔截,實現很是複雜。
  • 對象直接新添加的屬性或刪除已有屬性,界面不會自動更新,須要使用Vue.set()
  • 直接經過下標替換元素或更新length,界面也不會自動更新
  • 數據的響應式處理和視圖未徹底解耦

Vue3實現響應式的核心:
經過proxy代理:攔截對data任意屬性的任意操做,包括屬性值的讀寫,屬性的添加,屬性的刪除等。
經過reflect反射,動態對被代理對象的相應屬性進行特定的操做。code

//聲明一個普通對象,讓其變成一個proxy代理響應式對象
let user = {
  name: 'Liane',
  age: 18
}

//經過new運算符,實例化一個proxy對象,new Proxy(target, handler)
//參數一、target--目標對象
//參數二、handler--處理器對象,用來監視數據,及數據操做
let proxyUser = new Proxy(user, {
  //獲取目標對象的某個屬性值
  get(target, prop) {
    console.log('get方法調用了')
    //經過Reflect反射,對被代理對象(目標對象)的相應屬性進行特定操做
    return Reflect.get(target, prop)
  },
  //修改目標對象的屬性值/爲目標對象添加新的屬性
  set(target, prop, value) {
    console.log('set方法調用了')
    return Reflect.set(target, prop, value)
  },
  //刪除目標對象上的某個屬性值
  deleteProperty(target, prop) {
    console.log('delete方法調用了')
    return Reflect.deleteProperty(target, prop)
  }
})

console.log(proxyUser) //Proxy {name:"Liane",age:18}
//經過代理對象獲取目標對象中的某個屬性值
console.log(proxyUser.name) //Liane
//修改源對象的屬性,代理對象的值也會修改
user.name = 'Ann'
console.log(proxyUser.name) //Ann
//經過代理對象,修改目標對象上的屬性值
proxyUser.name = 'Rose'
console.log(user.name)  //Rose
//經過代理對象,刪除目標對象上的屬性值
delete proxyUser.name
console.log(user) //{age:18}
</script >

優勢:對象

  • 在咱們動態爲data添加屬性時,不須要作任何處理,這個屬性就已是響應式的了。(不用循環遍歷data的每一個屬性,對屬性都作一遍響應式處理,而是直接代理整個data對象)
  • 數組的任何操做也能夠觸發相應。
相關文章
相關標籤/搜索