国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

使用proxy實現(xiàn)一個更優(yōu)雅的vue【推薦】

2024-05-06 15:33:18
字體:
來源:轉載
供稿:網(wǎng)友

如果你有讀過Vue的源碼,或者有了解過Vue的響應原理,那么你一定知道Object.defineProperty(), 那么你也應該知道,Vue 2.x里,是通過 遞歸 + 遍歷 data 對象來實現(xiàn)對數(shù)據(jù)的監(jiān)控的, 你可能還會知道,我們使用的時候,直接通過數(shù)組的下標給數(shù)組設置值,不能實時響應,是因為Object.defineProperty() 無法監(jiān)控到數(shù)組下標的變化,而我們平常所用的數(shù)組方法 push , pop , shift , unshift , splice , sort , reverse , 其實不是真正的數(shù)組方法,而是被修改過的,這些都是因為 Object.defineProperty() 提供的能力有限,無法做到完美。

網(wǎng)上看過很多關于Vue的源碼解讀或者實現(xiàn)一個簡易版的Vue的教程,還都是用 Object.defineProperty (大概是為兼容性考慮吧), 而 Object.defineProperty() 確實存在諸多限制, 據(jù)說Vue的3.x版本會改用Proxy,那么今天我們就先來嘗嘗鮮,用Proxy實現(xiàn)一個簡單版的Vue

proxy 介紹

Proxy 用于修改某些操作的默認行為,等同于在語言層面做出修改,所以屬于一種“元編程”(meta programming),即對編程語言進行編程。

Proxy 可以理解成,在目標對象之前架設一層“攔截”,外界對該對象的訪問,都必須先通過這層攔截,因此提供了一種機制,可以對外界的訪問進行過濾和改寫。Proxy 這個詞的原意是代理,用在這里表示由它來“代理”某些操作,可以譯為“代理器”。

以上引用內(nèi)容來自阮一峰的es6教程的Proxy章節(jié) 原文地址請戳這里。

我們來看看如何用Proxy去定義一個監(jiān)聽數(shù)據(jù)的函數(shù)

定義 observe

_observe (data){ var that = this // 把代理器返回的對象存到 this.$data 里面 this.$data = new Proxy(data, { set(target,key,value){ // 利用 Reflect 還原默認的賦值操作 let res = Reflect.set(target,key,value) // 這行就是監(jiān)控代碼了 that.handles[key].map(item => {item.update()}) return res } })}

當觸發(fā)set的時候,就會執(zhí)行 that.handles[key].map(item => {item.update()}) ,這句代碼的作用就是執(zhí)行 該屬性名下的所有 "監(jiān)視器"

那么,監(jiān)視器怎么來的呢? 請繼續(xù)看以下代碼

定義 compile

_compile (root){ const nodes = Array.prototype.slice.call(root.children) let data = this.$data nodes.map(node => {  // 如果不是末尾節(jié)點,就遞歸  if(node.children.length > 0) this._complie(node)  // 處理 v-bind 指令  if(node.hasAttribute('v-bind')) {  let key = node.getAttribute('v-bind')  this._pushWatcher(new Watcher(node,'innerHTML',data,key))  }  // 處理 v-model 指令  if(node.hasAttribute('v-model')) {  let key = node.getAttribute('v-model')  this._pushWatcher(new Watcher(node,'value',data,key))  node.addEventListener('input',() => {data[key] = node.value})  }  // 處理 v-click 指令  if(node.hasAttribute('v-click')) {  let methodName = node.getAttribute('v-click')  let mothod = this.$methods[methodName].bind(data)  node.addEventListener('click',mothod)  } }) }            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 博湖县| 黄大仙区| 织金县| 仲巴县| 通道| 搜索| 东阿县| 沅陵县| 客服| 大港区| 桑植县| 溧水县| 商都县| 无锡市| 江阴市| 卢湾区| 新闻| 天门市| 乡宁县| 扎囊县| 皋兰县| 新乡县| 昆山市| 田阳县| 澄迈县| 泰兴市| 晋宁县| 基隆市| 汨罗市| 周宁县| 阳高县| 彝良县| 洛隆县| 繁峙县| 定边县| 丹巴县| 皮山县| 驻马店市| 揭阳市| 嘉祥县| 肇庆市|