91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

proxy怎么實現數據的雙向綁定

發布時間:2021-12-17 13:54:13 來源:億速云 閱讀:195 作者:iii 欄目:開發技術

本篇內容介紹了“proxy怎么實現數據的雙向綁定”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1.寫在前面

隨著 vue3.x 的消息越來越多,proxy 的討論也。相對于 Object.defineProperty ,proxy 有什么區別,有什么優勢,以及可以應用在什么地方。

2.Object.defineProperty

講 proxy 之前,先回顧下 Object.defineProperty 。大家都知道,vue2.x 以及之前的版本是使用 Object.defineProperty 實現數據的雙向綁定的,至于是怎樣綁定的呢?下面簡單實現一下

function observer(obj) {
   if (typeof obj ==='object') {
       for (let key in obj) {
           defineReactive(obj, key, obj[key])
       }
   }
}

function defineReactive(obj, key, value) {
   //針對value是對象,遞歸檢測
   observer(value)
   //劫持對象的key
   Object.defineProperty(obj, key, {
       get() {
           console.log('獲取:'+key)
           return value
       },
       set(val) {
           //針對所設置的val是對象
           observer(val)
           console.log(key+"-數據改變了")
           value = val
       }
   })
}

let obj={
   name:'守候',
   flag:{
       book:{
           name:'js',
           page:325
       },
       interest:['火鍋','旅游'],
   }
}

observer(obj)

在瀏覽器的 console 執行一下,似乎能正常運行

proxy怎么實現數據的雙向綁定

但是實際上,Object.defineProperty 問題有以下幾個

問題1.刪除或者增加對象屬性無法監聽到

比如增加一個屬性 gender ,由于在執行 observer(obj) 的時候,沒有這個屬性,所以這個無法監聽到。刪除的屬性也是無法監聽到

增加屬性的時候, vue 需要使用 $set 進行操作,$set 的內部也是使用 Object.defineProperty 進行操作

proxy怎么實現數據的雙向綁定

問題2.數組的變化無法監聽到

proxy怎么實現數據的雙向綁定

由上圖得知,雖然數組屬性實際上是修改成功了,但是不能被監聽到

問題3.由于是使用遞歸遍歷對象,使用 Object.defineProperty 劫持對象的屬性,如果遍歷的對象層級比較深,花的時間比較久,甚至有性能的問題

3.proxy

對于 proxy ,在 mdn 上的描述是: 對象用于定義基本操作的自定義行為(如屬性查找、賦值、枚舉、函數調用等)

簡單來說就是,可以在對目標對象設置一層攔截。無論對目標對象進行什么操作,都要經過這層攔截

聽上去似乎,proxy 比 Object.defineProperty 要好用,并且簡單很多,實際上就是如此。下面用 proxy 對上面的代碼進行改寫試下

function observerProxy(obj){
   let handler = {
     get (target, key, receiver) {
       console.log('獲取:'+key)
       // 如果是對象,就遞歸添加 proxy 攔截
       if (typeof target[key] === 'object' && target[key] !== null) {
         return new Proxy(target[key], handler)
       }
       return Reflect.get(target, key, receiver)
     },
     set (target, key, value, receiver) {
       console.log(key+"-數據改變了")
       return Reflect.set(target, key, value, receiver)
     }
   }
   return new Proxy(obj, handler)
} let obj={
   name:'守候',
   flag:{
       book:{
           name:'js',
           page:325
       },
       interest:['火鍋','旅游'],
   }
}

let objTest=observerProxy(obj)

也是一樣的效果

proxy怎么實現數據的雙向綁定

而且,能做到 Object.defineProperty 做不到的事情,比如增加一個屬性 gender,能夠監聽到

proxy怎么實現數據的雙向綁定

操作數組,也能監聽到

proxy怎么實現數據的雙向綁定

最后敲一下黑板,簡單總結一下兩者的區別

1.Object.defineProperty 攔截的是對象的屬性,會改變原對象。proxy 是攔截整個對象,通過 new 生成一個新對象,不會改變原對象。

2.proxy 的攔截方式,除了上面的 get 和 set ,還有 11 種。選擇的方式很多 Proxy,也可以監聽一些 Object.defineProperty 監聽不到的操作,比如監聽數組,監聽對象屬性的新增,刪除等。

4.proxy 使用場景

關于 proxy 的使用場景,受限于篇幅,這里就簡單列舉幾個,更多的可以移步我的 github 筆記或者 mdn。

看到這里,兩者的區別,和 proxy 的優勢已經知道個大概了。但是在開發上,有哪些場景可以使用到 proxy 呢,下面列舉個可能會遇上的情況

4-1.負索引數組

在使用 splice(-1),slice(-1) 等 API 的時候,當輸入負數的時候,會定位到數組的最后一項,但是在普通數組上,并不能使用負數。 [1,2,3][-1] 這個代碼并不能輸出 3 。要讓上面的代碼輸出 3 , 也可以使用 proxy 實現。

let ecArrayProxy = {
 get (target, key, receiver) {
   let _index=key<0?target.length+Number(key):key
   return Reflect.get(target, _index, receiver)
 }
}
let arr=new Proxy([1,2,3],ecArrayProxy)

proxy怎么實現數據的雙向綁定

4-2.表單校驗

在對表單的值進行改動的時候,可以在 set 里面進行攔截,判斷值是否合法

let ecValidate = {
 set (target, key, value, receiver) {
   if (key === 'age') {
     //如果值小于0,或者不是正整數
     if (value<0||!Number.isInteger(value)) {
       throw new TypeError('請輸入正確的年齡');
     }
   }
   return Reflect.set(target, key, value, receiver)
 }
}

let obj=new Proxy({age:18},ecValidate)
obj.age=16
obj.age='少年'

proxy怎么實現數據的雙向綁定

4-3.增加附加屬性

比如有一個需求,保證用戶輸入正確身份證號碼之后,把出生年月,籍貫,性別都添加進用戶信息里面

眾所周知,身份證號碼第一和第二位代表所在省(自治區,直轄市,特別行政區),第三和第四位代表所在市(地級市、自治州、盟及國家直轄市所屬市轄區和縣的匯總碼)。第七至第十四位是出生年月日。低17位代表性別,男單女雙。

const PROVINCE_NUMBER={
   44:'廣東省',
   46:'海南省'
}
const CITY_NUMBER={
   4401:'廣州市',
   4601:'海口市'
}

let ecCardNumber = {
 set (target, key, value, receiver) {
   if(key === 'cardNumber'){
       Reflect.set(target, 'hometown', PROVINCE_NUMBER[value.substr(0,2)]+CITY_NUMBER[value.substr(0,4)], receiver)
       Reflect.set(target, 'date', value.substr(6,8), receiver)
       Reflect.set(target, 'gender', value.substr(-2,1)%2===1?'男':'女', receiver)
   }
   return Reflect.set(target, key, value, receiver)
 }
}
let obj=new Proxy({cardNumber:''},ecCardNumber)

proxy怎么實現數據的雙向綁定

4-4.數據格式化

比如有一個需求,需要傳時間戳給到后端,但是前端拿到的是一個時間字符串,這個也可以用 proxy 進行攔截,當得到時間字符串之后,可以自動加上時間戳。

let ecDate = {
 set (target, key, value, receiver) {
   if(key === 'date'){
       Reflect.set(target, 'timeStamp', +new Date(value), receiver)
   }
   return Reflect.set(target, key, value, receiver)
 }
}
let obj=new Proxy({date:''},ecDate)

proxy怎么實現數據的雙向綁定

“proxy怎么實現數據的雙向綁定”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梨树县| 昆明市| 衢州市| 黔南| 赞皇县| 滁州市| 新乡市| 曲松县| 加查县| 五莲县| 南丹县| 金寨县| 河北区| 北海市| 集贤县| 延川县| 莱芜市| 琼海市| 朝阳区| 寿宁县| 道孚县| 天祝| 康定县| 亳州市| 乐昌市| 白银市| 县级市| 永川市| 荥经县| 宜宾市| 泸州市| 舒城县| 山东| 时尚| 汉源县| 正阳县| 鹰潭市| 通化市| 册亨县| 宜春市| 仁怀市|