日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy

發(fā)布時(shí)間:2023/12/4 vue 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一文了解Vue3的響應(yīng)式原理

  • 一、🟩回顧Object.defineProperty
  • 二、🟨Proxy基本使用
  • 三、🟦學(xué)習(xí)Proxy語法:Reflect
  • 四、🟧Vue3如何用Proxy實(shí)現(xiàn)響應(yīng)式
    • 1、實(shí)現(xiàn)響應(yīng)式
    • 2、Proxy總結(jié)
      • (1)深度監(jiān)聽,性能更好
      • (2)可監(jiān)聽 新增/刪除 屬性
      • (3)可監(jiān)聽數(shù)組變化
    • 3、兩者對(duì)比
  • 五、🟪結(jié)束語

之前寫過一篇文章談?wù)?vue2.x 的響應(yīng)式原理,但因?yàn)?vue3 也來了,緊跟著 vue3 的步伐,周一開始學(xué)起了 vue3 的響應(yīng)式原理。

大家應(yīng)該都聽過, vue3 用 proxy 來解決響應(yīng)式原理,同時(shí)它解決了 vue2 中 Object.definePropery 存在的一些問題,但同時(shí)也帶來了一些問題。

在下面的這篇文章中,將講解關(guān)于 vue3 用 proxy 如何實(shí)現(xiàn)響應(yīng)式,以及帶來的一些問題。一起來學(xué)習(xí)吧💯

一、🟩回顧Object.defineProperty

這里需要大家對(duì) ObjectProperty 的知識(shí)點(diǎn)有一個(gè)預(yù)先了解,如有需要了解可點(diǎn)擊文章進(jìn)行查看~

現(xiàn)在,我們來回顧下 Object.defineProperty 的缺點(diǎn):

  • 深度監(jiān)聽時(shí)需要一次性遞歸;
  • 無法監(jiān)聽新增屬性/刪除屬性(需要配合 Vue.set 或 Vue.delete 使用);
  • 無法原生監(jiān)聽數(shù)組,需要特殊處理。

帶著 Object.defineProperty 的這幾個(gè)缺點(diǎn),接下來我們開始進(jìn)入 Proxy 的世界。

二、🟨Proxy基本使用

下面用一段代碼來演示 Proxy 的基本使用。具體代碼如下:

const data = {name: 'monday',age:18 } //const data = ['a', 'b', 'c']const proxyData = new Proxy(data, {get(target, key, receiver){//只處理本身(非原型的)屬性const ownKeys = Reflect.ownKeys(target)if(oenKeys.includes(key)){console.log('get', key) //監(jiān)聽}const result = Reflect.get(target, key, receiver)return result // 返回結(jié)果},set(target, key, val, receiver){//重復(fù)的數(shù)據(jù),不處理if(val === target[key]){return true}const result = Reflect.set(target, key, val, receiver)console.log('set', key, val)//console.log('result', result) //truereturn result // 是否設(shè)置成功},deleteProperty(target, key){const result = Reflect.deleteProperty(target, key)console.log('delete property', key)return result // 是否刪除成功} })

通過以上代碼可得,我們先定義一個(gè)對(duì)象字面量的 data ,之后在作為 Proxy 實(shí)例化的參數(shù)進(jìn)行傳遞。且 proxyData 實(shí)現(xiàn)了 get 、 set 和 deleteProperty 的方法,可以對(duì)數(shù)據(jù)進(jìn)行增刪改操作。

三、🟦學(xué)習(xí)Proxy語法:Reflect

我們?cè)賮碚J(rèn)識(shí) Proxy 的一個(gè)好朋友,Reflect。

Reflect 對(duì)象有著和 Proxy 一一對(duì)應(yīng)的能力,Reflect對(duì)象一共有 13 個(gè)靜態(tài)方法,這也就是我們平常所聽到的 proxy 有多達(dá)13種攔截行為,而 Reflect 的這13種靜態(tài)方法匹配的就是 Proxy 的13種攔截行為

靜態(tài)方法列表
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.has(obj, name)
Reflect.deleteProperty(obj, name)
Reflect.construct(target, args)
Reflect.getPrototypeOf(obj)
Reflect.setPrototypeOf(obj, newProto)
Reflect.apply(func, thisArg, args)
Reflect.defineProperty(target, propertyKey, attribute)
Reflect.getOwnPropertyDescriptor(target, propertyKey)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.ownKeys(target)

Reflect 的出現(xiàn)是為了替換掉 Object 上的工具函數(shù),這里不做具體介紹,詳情可查看文檔 。

四、🟧Vue3如何用Proxy實(shí)現(xiàn)響應(yīng)式

1、實(shí)現(xiàn)響應(yīng)式

下面來實(shí)現(xiàn)Proxy的響應(yīng)式。附上代碼:

// 創(chuàng)建響應(yīng)式 function reactive(target = {}) {if (typeof target !== 'object' || target == null) {// 不是對(duì)象或數(shù)組,則返回return target}// 代理配置const proxyConf = {get(target, key, receiver) {// 只處理本身(非原型的)屬性const ownKeys = Reflect.ownKeys(target)if (ownKeys.includes(key)) {console.log('get', key) // 監(jiān)聽}const result = Reflect.get(target, key, receiver)// 深度監(jiān)聽return reactive(result)},set(target, key, val, receiver) {// 重復(fù)的數(shù)據(jù),不處理if (val === target[key]) {return true}const ownKeys = Reflect.ownKeys(target)// 判斷是已有屬性還是新增屬性if (ownKeys.includes(key)) {console.log('已有的 key', key)} else {console.log('新增的 key', key)} const result = Reflect.set(target, key, val, receiver)console.log('set', key, val)// console.log('result', result) // truereturn result // 是否設(shè)置成功},deleteProperty(target, key) {const result = Reflect.deleteProperty(target, key)console.log('delete property', key)// console.log('result', result) // truereturn result // 是否刪除成功}}// 生成代理對(duì)象const observed = new Proxy(target, proxyConf)return observed }// 測(cè)試數(shù)據(jù) const data = {name: 'monday',age: 18,info: {city: 'FuZhou',a: {b: {c: {d: {e: 100}}}}} }const proxyData = reactive(data)

我們?cè)诳刂婆_(tái)來驗(yàn)證數(shù)據(jù):

從上圖中可以看到,用 proxy 來實(shí)現(xiàn)響應(yīng)式,如果遇到需要深度遞歸的數(shù)組時(shí),它不會(huì)像 defineProperty 那樣深度遞歸,它會(huì)在什么時(shí)候 get ,什么時(shí)候再深度遞歸。本質(zhì)上來講就是,你獲取到哪一層,那一層才會(huì)觸發(fā)響應(yīng)式。你獲取不到的深層,它就不會(huì)觸發(fā)響應(yīng)式。且從代碼中我們可以了解到, Proxy 在修改屬性時(shí),如果數(shù)據(jù)是重復(fù)的,則不進(jìn)行處理。如果數(shù)據(jù)不重復(fù),再進(jìn)行處理。這樣一來,就極大程度上提高了軟件的性能。

2、Proxy總結(jié)

現(xiàn)在來對(duì)上述Proxy的內(nèi)容做一個(gè)總結(jié):

(1)深度監(jiān)聽,性能更好

defineProperty 是一次性遞歸完成;而 Proxy 是什么時(shí)候 get ,什么時(shí)候再深度遞歸。

(2)可監(jiān)聽 新增/刪除 屬性

在 vue2 中, defineProperty 是無法新增/刪除屬性的,需要配合 Vue.set 和 Vue.delete 來使用,而在 Vue3 中, Proxy 可以新增和刪除屬性,無需進(jìn)行特殊處理。

(3)可監(jiān)聽數(shù)組變化

在 vue2 中,監(jiān)聽數(shù)組變化是需要進(jìn)行特殊處理,且只能一次性深度遞歸完成。而在 vue3 中,可以監(jiān)聽數(shù)組變化,并且是什么時(shí)候get什么時(shí)候再遞歸,獲取不到的深層,不會(huì)觸發(fā)響應(yīng)式。

3、兩者對(duì)比

講到這里,我們?cè)侔?vue2 中的 Object.defineProperty 和 vue3 中的 Proxy 做一個(gè)對(duì)比:

  • Proxy 能良好的規(guī)避 Object.defineProperty 的問題;
  • Proxy 無法兼容所有瀏覽器(如 IE11 ),且無法 polyfill 。

五、🟪結(jié)束語

從某種程度上來說, vue3 的 Proxy 確實(shí)帶來了一些好處,但同時(shí)也帶來了一些問題。正因?yàn)槿绱?#xff0c; vue2 的 Object.defineProperty 還會(huì)存在很長(zhǎng)一段時(shí)間。所以,新技術(shù)的使用總會(huì)經(jīng)過一個(gè)從試用階段到穩(wěn)定階段的過程。

關(guān)于vue3的響應(yīng)式原理講到這里就結(jié)束啦!如有疑問或文章有誤歡迎評(píng)論區(qū)留言或私信交流~

  • 關(guān)注公眾號(hào) 星期一研究室 ,第一時(shí)間關(guān)注技術(shù)干貨,更多有趣的專欄待你解鎖~
  • 如果這篇文章對(duì)你有用,記得 一鍵三連 再走哦!
  • 我們下期見!🥂🥂🥂

總結(jié)

以上是生活随笔為你收集整理的vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。