成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

VUE - MVVM - part4 - 優(yōu)化Watcher

CoffeX / 2425人閱讀

摘要:關(guān)于中的的實現(xiàn),差不多也就這樣了,當(dāng)然這僅僅是基礎(chǔ)的實現(xiàn),而且視圖層層渲染抽象成一個函數(shù)。不同于中的實現(xiàn),這里少了很多各種標(biāo)記和應(yīng)用標(biāo)記的過程。

看這篇之前,如果沒有看過之前的文章,可拉到文章末尾查看之前的文章。

回顧

首先我們思考一下截止當(dāng)前,我們都做了什么

通過 defineReactive 這個函數(shù),實現(xiàn)了對于數(shù)據(jù)取值和設(shè)置的監(jiān)聽

通過 Dep 類,實現(xiàn)了依賴的管理

通過 Watcher 類,抽象出了對象下某個屬性的依賴,以及屬性變換的 callBack

發(fā)現(xiàn)問題

對比 VueMVVM(先把視圖層的渲染抽象成一個函數(shù)),我們僅僅是實現(xiàn)了一些基礎(chǔ)性的東西。還有很大的區(qū)別,比如

我們的 Watcher 僅僅是抽象了對象下的單一屬性,而一般視圖層的渲染是涉及多個屬性的,而這些屬性的變化是同一個渲染函數(shù)(也就是 Vue 中編譯模板字符串最終生成的函數(shù))。

通過第一點,我們可以得知,對象下的某幾個屬性是擁有同一個 Watcher 的,換句話說就是,多個 Dep 依賴與同一個 Watcher,那么 Watcher 中該如何保存這些 Dep ,因為按照我們的實現(xiàn),都一個 Watcher 中僅僅保持一個 Dep

解決問題 問題1

先讓我們想想,我們是如何把依賴注入到 Dep 中的

通過取值觸發(fā) defineProperty 中的 get,然后添加依賴

換句話說就是,我只要取過對應(yīng)屬性的值,那么就可以添加依賴。
看到之前 Watcher 的實現(xiàn):

this.get = function () {
    Dep.target = this
    let value = this.getter.call(object)
    Dep.target = null
    return value
}

這段代碼就實現(xiàn)了添加相應(yīng)屬性的依賴,歸根到底是這段起了作用

let value = this.obj[this.getter]

這里觸發(fā)了對應(yīng)屬性的 get ,那好針對第一個問題,我們只要在這里觸發(fā)多個屬性的 get 即可,至于要觸發(fā)那些屬性,我們交由調(diào)用者來控制,順理成章的這里應(yīng)該是一個函數(shù)。考慮之后便有了以下代碼

let Watcher = function (object, getter, callback) {
    this.obj = object
    // 這里的 getter 應(yīng)該是一個函數(shù)
    this.getter = getter
    this.cb = callback
    this.dep = null
    this.value = undefined

    this.get = function () {
        Dep.target = this
        // 將取值方式改成函數(shù)調(diào)用
        let value = this.getter.call(object)
        Dep.target = null
        return value
    }

    this.update = function () {
        const value = this.getter.call(object)
        const oldValue = this.value
        this.value = value
        this.cb.call(this.obj, value, oldValue)
    }

    this.addDep = function (dep) {
        this.dep = dep
    }

    this.value = this.get()
}
問題二

問題二其實很簡單,既然要保存多個 dep 我們把保存的值聲明成一個數(shù)組即可

let Watcher = function (object, getter, callback) {
    this.obj = object
    this.getter = getter
    this.cb = callback
    // 聲明成數(shù)組
    this.deps = []
    this.value = undefined

    this.get = function () {
        Dep.target = this
        let value = this.getter.call(object)
        Dep.target = null
        return value
    }

    this.update = function () {
        const value = this.getter.call(object)
        const oldValue = this.value
        this.value = value
        this.cb.call(this.obj, value, oldValue)
    }

    this.addDep = function (dep) {
        // 將 dep 推入數(shù)組中
        this.deps.push(dep)
    }

    this.value = this.get()
}

為了方便取消這個 Watcher ,我們在添加一個函數(shù),用于取消所有 DepWatcher 的依賴,所以最終 Watcher 的代碼如下:

let Watcher = function (object, getter, callback) {
    this.obj = object
    this.getter = getter
    this.cb = callback
    this.deps = []
    this.value = undefined

    this.get = function () {
        Dep.target = this
        let value = this.getter.call(object)
        Dep.target = null
        return value
    }

    this.update = function () {
        const value = this.getter.call(object)
        const oldValue = this.value
        this.value = value
        this.cb.call(this.obj, value, oldValue)
    }

    this.addDep = function (dep) {
        this.deps.push(dep)
    }

    // 新添加的取消依賴的方法
    this.teardown = function () {
        let i = this.deps.length
        while (i--) {
            this.deps[i].removeSub(this)
        }
        this.deps = []
    }

    this.value = this.get()
}
測試

我們僅僅優(yōu)化了 Watcher 的實現(xiàn),其他的代碼并沒有發(fā)生變化

let object = {}
defineReactive(object, "num1", 2)
defineReactive(object, "num2", 4)

let watcher = new Watcher(object, function () {
    return this.num1 + this.num2
}, function (newValue, oldValue) {
    console.log(`這是一個監(jiān)聽函數(shù),${object.num1} + ${object.num2} = ${newValue}`)
})

object.num1 = 3
// 這是一個監(jiān)聽函數(shù),3 + 4 = 7
object.num2 = 10
// 這是一個監(jiān)聽函數(shù),3 + 10 = 13

let watcher2 = new Watcher(object, function () {
    return this.num1 * this.num2
}, function (newValue, oldValue) {
    console.log(`這是一個監(jiān)聽函數(shù),${object.num1} * ${object.num2} = ${newValue}`)
})

object.num1 = 4
// 這是一個監(jiān)聽函數(shù),4 + 10 = 14
// 這是一個監(jiān)聽函數(shù),4 * 10 = 40
object.num2 = 11
// 這是一個監(jiān)聽函數(shù),4 + 11 = 15
// 這是一個監(jiān)聽函數(shù),4 * 11 = 44

// 測試取消
watcher2.teardown()

object.num1 = 5
// 這是一個監(jiān)聽函數(shù),5 + 11 = 16
object.num2 = 12
// 這是一個監(jiān)聽函數(shù),5 + 12 = 17

這就實現(xiàn)了對于多個屬性設(shè)置同一個監(jiān)聽,當(dāng)監(jiān)聽函數(shù)中的依賴屬性發(fā)生變化時,自動執(zhí)行了相應(yīng)的函數(shù)。

關(guān)于 Vue 中的 MVVM 的實現(xiàn) ,差不多也就這樣了,當(dāng)然這僅僅是基礎(chǔ)的實現(xiàn),而且視圖層層渲染抽象成一個函數(shù)。

不同于 Vue 中的實現(xiàn),這里少了很多各種標(biāo)記和應(yīng)用標(biāo)記的過程。

這些會增加理解難度,之后有用到再說,實現(xiàn)完整的 MVVM 還需要對數(shù)組進行特殊的處理,因為數(shù)組是不能用 Object.defineProperty 來處理索引值的,這個也之后再說。

點擊查看相關(guān)代碼

系列文章地址

VUE - MVVM - part1 - defineProperty

VUE - MVVM - part2 - Dep

VUE - MVVM - part3 - Watcher

VUE - MVVM - part4 - 優(yōu)化Watcher

VUE - MVVM - part5 - Observe

VUE - MVVM - part6 - Array

VUE - MVVM - part7 - Event

VUE - MVVM - part8 - 優(yōu)化Event

VUE - MVVM - part9 - Vue

VUE - MVVM - part10 - Computed

VUE - MVVM - part11 - Extend

VUE - MVVM - part12 - props

VUE - MVVM - part13 - inject & 總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/94210.html

相關(guān)文章

  • VUE - MVVM - part3 - Watcher

    摘要:解決第一個問題很簡單,我們把某個屬性的值對應(yīng)值變化時需要執(zhí)行的函數(shù)抽象成一個對象,然后把這個對象當(dāng)成是依賴,推入依賴管理中。的實現(xiàn)有了以上的考慮,那個依賴對象在中就是。新值作為添加的第一個函數(shù),很自豪。 看這篇之前,如果沒有看過之前的文章,可拉到文章末尾查看之前的文章。 前言 在 step2 中,我們實現(xiàn)了一個管理依賴的 Dep ,但是僅僅使用這個類并不能完成我們想實現(xiàn)的功能,而且代碼...

    wums 評論0 收藏0
  • VUE - MVVM - part5 - Observe

    摘要:具體代碼執(zhí)行方式進入到的目錄下,命令行運行即可。確保為一個對象如果對象下有則不需要再次生成函數(shù)返回該對象的實例,這里判斷了如果該對象下已經(jīng)有實例,則直接返回,不再去生產(chǎn)實例。這就確保了一個對象下的實例僅被實例化一次。 看這篇之前,如果沒有看過之前的文章,可拉到文章末尾查看之前的文章。 回顧 在 step4 中,我們大致實現(xiàn)了一個 MVVM 的框架,由3個部分組成: defineRe...

    xi4oh4o 評論0 收藏0
  • VUE - MVVM - part10 - Computed

    摘要:了解之后我們來實現(xiàn)它,同樣的為了方便理解我寫成了一個類這里的一般是的實例將屬性代理到實例下的構(gòu)造函數(shù)我們實現(xiàn)了代理屬性和更新計算屬性的值,同時依賴沒變化時,也是不會觸發(fā)的更新,解決了以上的個問題。 看這篇之前,如果沒有看過之前的文章,移步拉到文章末尾查看之前的文章。 回顧 先捋一下,之前我們實現(xiàn)的 Vue 類,主要有一下的功能: 屬性和方法的代理 proxy 監(jiān)聽屬性 watche...

    callmewhy 評論0 收藏0
  • VUE - MVVM - part9 - Vue

    摘要:調(diào)用父類的方法類在我們上一步已經(jīng)實現(xiàn)。我們先實現(xiàn)的綁定,因為是要被監(jiān)聽,所以要進行進一步的處理。調(diào)用父類的方法方法綁定完事,其實就這么簡單。 看這篇之前,如果沒有看過之前的文章,可拉到文章末尾查看之前的文章。 前言 激動人心的時候即將來臨,之前我們做的 8 步,其實都在為這一步打基礎(chǔ),這一步,我們來簡單實現(xiàn)一個 Vue 對象,還沒有看過之前代碼的同學(xué),請確認(rèn)看過之前的文章。 主要實現(xiàn)內(nèi)...

    yzd 評論0 收藏0
  • VUE - MVVM - part2 - Dep

    摘要:看這篇之前,如果沒看過先移步看實現(xiàn)中。同樣的,在取值時收集依賴,在設(shè)置值當(dāng)值發(fā)生變化時觸發(fā)依賴。中實現(xiàn)了一個的類來處理以上兩個問題,之后再說。以下語法下的,源碼中差不多就這樣點擊查看相關(guān)代碼系列文章地址優(yōu)化優(yōu)化總結(jié) 看這篇之前,如果沒看過 step1 先移步看 實現(xiàn) VUE 中 MVVM - step1 - defineProperty。 在上一篇我們大概實現(xiàn)了,Vue 中的依賴收集和...

    hover_lew 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<