最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2018年06月19日 11:24:30   作者:noahlam  
Proxy 用于修改某些操作的默認(rèn)行為,等同于在語言層面做出修改,所以屬于一種“元編程”。這篇文章主要介紹了用proxy實(shí)現(xiàn)一個(gè)更優(yōu)雅的vue,需要的朋友可以參考下

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

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

proxy 介紹

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

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

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

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

定義 observe

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

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

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

定義 compile

_compile (root){
 const nodes = Array.prototype.slice.call(root.children)
 let data = this.$data
 nodes.map(node => {
  // 如果不是末尾節(jié)點(diǎn),就遞歸
  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)
  }
 })
 }

上面這段代碼,看起來很長,可是實(shí)際上,只做了意見很簡(jiǎn)單的事情, 就是 "編譯" html 模板 ,把有 v-bind 、 v-model 、 v-click 都給加上對(duì)應(yīng)的 通知 和 監(jiān)控

1.通知就是 this._pushWatcher(...) , 相當(dāng)于是安裝一個(gè)監(jiān)聽器,這樣只要 this.$data 有發(fā)生 set 操作的話,就會(huì)執(zhí)行 this._pushWatcher 括號(hào)里面?zhèn)鞯暮瘮?shù),來通知節(jié)點(diǎn)更新數(shù)據(jù)

2.監(jiān)控就是 node.addEventListener(...) 監(jiān)聽相應(yīng)的事件,然后執(zhí)行對(duì)應(yīng)的 watcher 或者 methods

this._pushWatcher 又做了什么呢?

_pushWatcher (watcher) {
 if (!this._binding[watcher.key]) this._binding[watcher.key] = []
 this._binding[watcher.key].push(watcher)
 }

這個(gè)就更簡(jiǎn)單了,如果 this._binding[watcher.key] 為空,就初始化,然后向里面添加一個(gè) 監(jiān)聽器

最后,我們?cè)賮砜纯?,監(jiān)聽器是怎么實(shí)現(xiàn)的

定義 Watcher

class Watcher {
 constructor (node,attr,data,key) {
 this.node = node
 this.attr = attr
 this.data = data
 this.key = key
 }
 update () {
 this.node[this.attr] = this.data[this.key]
 }
 }

Watcher 是一個(gè)類,只有一個(gè)方法,就是更新數(shù)據(jù),怎么知道要更新哪個(gè)節(jié)點(diǎn),更新為什么數(shù)據(jù)呢? 在實(shí)例化(new)的時(shí)候,傳的參數(shù)就是定義這些的

這樣,我們就實(shí)現(xiàn)初步的雙向綁定了,整個(gè)代碼大概只有50行。其實(shí)還可以更少, 但是更少的話,就是繼續(xù)閹割功能了(雖然目前實(shí)現(xiàn)的也是嚴(yán)重閹割版的), 但是我覺得實(shí)現(xiàn)這些,剛好可以不多不少幫我我們理解vue的本質(zhì)。

最后

本文最終實(shí)現(xiàn)代碼已經(jīng)放在 github 上,想要直接看效果的同學(xué),可以上去直接copy,運(yùn)行。

如果覺得本文對(duì)您有用,請(qǐng)給本文的github 加個(gè)star,萬分感謝

另外, github 上還有其他一些關(guān)于前端的教程和組件,有興趣的童鞋可以看看,你們的支持就是我最大的動(dòng)力。

總結(jié)

以上所述是小編給大家介紹的使用proxy實(shí)現(xiàn)一個(gè)更優(yōu)雅的vue,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • vue?3.0?使用ref獲取dom元素的示例

    vue?3.0?使用ref獲取dom元素的示例

    這篇文章主要介紹了vue?3.0?使用ref獲取dom元素,包括vue2.x獲取dom和vue3.0獲取單個(gè)dom,通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • vue3引入ElementUI報(bào)錯(cuò)問題及解決

    vue3引入ElementUI報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了vue3引入ElementUI報(bào)錯(cuò)問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時(shí)的示例代碼

    Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時(shí)的示例代碼

    Vue3的Hooks是一種新的 API,本文主要介紹了Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時(shí)的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • 關(guān)于vue中@click.native.prevent的說明

    關(guān)于vue中@click.native.prevent的說明

    這篇文章主要介紹了關(guān)于vue中@click.native.prevent的說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • uniapp自定義導(dǎo)航欄新手保姆級(jí)教程

    uniapp自定義導(dǎo)航欄新手保姆級(jí)教程

    uniapp的頂部導(dǎo)航欄有時(shí)候不符合設(shè)計(jì)需求,我們可以自定義頂部導(dǎo)航欄,下面這篇文章主要給大家介紹了關(guān)于uniapp自定義導(dǎo)航欄的保姆級(jí)教程,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    在 Vue 3 中使用 Element-Plus 的 el-upload 組件進(jìn)行文件上傳時(shí),有時(shí)候需要限制只能上傳一個(gè)文件,本文將介紹如何通過配置 el-upload 組件實(shí)現(xiàn)這個(gè)功能,讓你的文件上傳變得更加簡(jiǎn)潔和易用,需要的朋友可以參考下
    2023-10-10
  • Vue.js進(jìn)階知識(shí)點(diǎn)總結(jié)

    Vue.js進(jìn)階知識(shí)點(diǎn)總結(jié)

    給大家分享了關(guān)于Vue.js想成為高手的5個(gè)總要知識(shí)點(diǎn),需要的朋友可以學(xué)習(xí)下。
    2018-04-04
  • vscode 插件開發(fā) + vue的操作方法

    vscode 插件開發(fā) + vue的操作方法

    這篇文章主要介紹了vscode 插件開發(fā) + vue的操作方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • vue 解決數(shù)組賦值無法渲染在頁面的問題

    vue 解決數(shù)組賦值無法渲染在頁面的問題

    今天小編就為大家分享一篇vue 解決數(shù)組賦值無法渲染在頁面的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • 對(duì)vue事件的延遲執(zhí)行實(shí)例講解

    對(duì)vue事件的延遲執(zhí)行實(shí)例講解

    今天小編就為大家分享一篇對(duì)vue事件的延遲執(zhí)行實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08

最新評(píng)論

云安县| 青川县| 沽源县| 泸溪县| 通州区| 墨竹工卡县| 诏安县| 无为县| 乐昌市| 普安县| 海丰县| 天等县| 宿迁市| 虹口区| 甘南县| 行唐县| 星座| 张北县| 从江县| 宜黄县| 高青县| 安乡县| 上饶县| 韩城市| 三台县| 鹤峰县| 兰溪市| 应用必备| 彩票| 和平县| 葵青区| 防城港市| 峨边| 宣城市| 屏山县| 日照市| 呼和浩特市| 会理县| 肃宁县| 高州市| 铜陵市|