欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實現(xiàn)雙向數(shù)據(jù)綁定

 更新時間:2021年05月19日 14:29:58   作者:Goodbye_yesterday  
這篇文章主要為大家詳細介紹了vue實現(xiàn)雙向數(shù)據(jù)綁定,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了vue實現(xiàn)雙向數(shù)據(jù)綁定的具體代碼,供大家參考,具體內(nèi)容如下

vue中數(shù)組與對象采用了不同的綁定方式

1.vue對象數(shù)據(jù)綁定

(1)數(shù)據(jù)偵測

在js中,我們使用Object.defineProperty()和ES6的proxy來對對象進行偵測

在vue2.x中使用的是Object.defineProperty()來對對象進行數(shù)據(jù)偵測,我們首先對Object.defineProperty進行封裝,有如下的代碼:

function defineReactive(data, key, val){
    if(typeof val === 'object') new Observer(val)
    let dep = new Dep();
    Object.defineProperty(data, key, val) {
    enumerable: true,
    configurable: true,
    get: function () {
        dep.depend();
        return val;
    },
    set: function() {
        if(val === newVal) {
            return ;
        }
        val = newVal;
        dep.notify()
    }
}
}

需要傳遞的參數(shù)只有data, key, val,每當從data中的key中讀取數(shù)據(jù)的時候觸發(fā)get,修改的數(shù)據(jù)的時候觸發(fā)set

(2)依賴收集

先收集依賴,等到屬性發(fā)生改變的時候,再把收集到的依賴循環(huán)觸發(fā)一遍就好了,在getter中收集依賴,在setter中觸發(fā)依賴

依賴類Dep

export default class Dep {
    constructor() {
        this.subs = []
    }
    
    addSub() {
        this.subs.push(sub)
    }
    
    removeSub(sub) {
        remove(this.subs, sub)
    }
    
    depend() {
        if(window.target) {
            this.addSub(window.target)
        }
    }
    
    notify() {
        const subs = this.subs.slice()
        for(let i = 0, l = subs.length; i < l; i++) {
            subs[i].update()
        }
    }
}
 
function remove(arr, item) {
    if(arr.length) {
        const index = arr.indexOf(item)
        if(index > -1) {
            return arr.splice(index, 1)
        }
}
}

watcher類是我們收集的依賴

export default class Watcher {
    constructor(vm, expOrFn, cb) {
        this.vm = vm
        this.getter = parsePath(expOrFn)
        this.cb = cb
        this.value = this.get()
    }
    
    get() {
        window.target = this
        let value = this.getter.call(this.vm, this.vm)
        window.target = undefined
        return value
    }
    
    update() {
        const oldValue = this.value
        this.value = this.get()
        this.cb.call(this.vm, this.value, oldValue)
    }
}

(3)遞歸偵測所有key (Observer) 

export class Observer {
    constructor(value) {
        this.value = value;
        
        if(!Array.isArray(value)) {
            this.walk(value)
        }
    }
    walk(obj) {
        const keys = Object.keys(obj)
        for(let i = 0; i < keys.length; i++) {
            defineReactive(obj, keys[i], obj[keys[i]])
        }
    }
}

Observer類就是將對象的所有屬性變?yōu)轫憫?yīng)式的

2.Array的變化偵測

(1)數(shù)組中追蹤變化用的是攔截器覆蓋原型方法

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto);
//和數(shù)組原型一樣的對象作為攔截器
['push','pop','shift','unshift','splice','sort','reverse'].forEach(function (method) {
    const original = arrayProto[method]
    Object.defineProperty(arrayMethods, method, {
        value: function mutator(...args) {
              return original.apply(this, args)
        },
        enumerable: false,
        writable: true,
        configurable: true
    })
})

攔截器覆蓋原型只有一句話

value.__proto__ = arrayMethods

如果沒有__proto__屬性,vue將會把這些arrayMethods掛載到被偵測的數(shù)組上

數(shù)組與對象類似,都是在getter中收集依賴,而數(shù)組觸發(fā)依賴實在攔截器里面

數(shù)組的依賴保存在Observer實例上,依賴必須是getter和攔截器中都可以訪問到的

__ob__是不可枚舉屬性,這個屬性的值就是當前Observer實例

把Dep實例保存在Observer的屬性上,如果value已經(jīng)有__ob__屬性,則不需要重復(fù)創(chuàng)建Observer實例,避免重復(fù)偵測value的變化

像數(shù)組的依賴發(fā)送通知

this.__ob__.dep.notify();

(2).偵測數(shù)據(jù)變化的具體方法

循環(huán)數(shù)組中的每一項,執(zhí)行observe函數(shù)來偵測變化

observeArray(items) {
    for(let i = 0; l = items.length; i < l; i++) {
        observe(items[i]);    
    }
}

數(shù)組需要偵測新的元素

通過攔截push,unshift,splice等方法,并且把args存儲在inserted中

if(inserted) ob.observeArray(inserted)

總結(jié):

Array追蹤變化的方式和Object不一樣,所以我們通過創(chuàng)建攔截器去覆蓋數(shù)組原型的方式來追蹤變化,為了不污染全局Array.prototype,我們在Observer中只針對需要偵測變化的數(shù)組使用__proto__來覆蓋原型。

Array收集依賴的方式和Object一樣,都在getter中收集,在攔截器中觸發(fā),依賴保存在Observer實例上。在Observer上,我們每個偵測的數(shù)據(jù)都標記上了__ob__,并把this(Observer)保存在__ob__上,主要是為了保證同一數(shù)據(jù)只被偵測一次,另外可以很方便的通過__ob__從而拿到Observer實例上保存的依賴。數(shù)組需要循環(huán)把每一個數(shù)組項都變成響應(yīng)式的,當數(shù)組中新增元素的時候,我們把參數(shù)提取出來,然后使用observeArray對新增的數(shù)據(jù)進行變化偵測,對于數(shù)組,只能攔截原型方法,對于一些特有的方法就無法攔截。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue結(jié)合AntV?G2的使用踩坑記錄

    vue結(jié)合AntV?G2的使用踩坑記錄

    這篇文章主要介紹了vue結(jié)合AntV?G2的使用踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue中關(guān)于checkbox使用的問題

    vue中關(guān)于checkbox使用的問題

    這篇文章主要介紹了vue中關(guān)于checkbox使用的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 淺談Vue.nextTick 的實現(xiàn)方法

    淺談Vue.nextTick 的實現(xiàn)方法

    本篇文章主要介紹了Vue.nextTick 的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • vue3實現(xiàn)點擊空白區(qū)域隱藏div

    vue3實現(xiàn)點擊空白區(qū)域隱藏div

    這篇文章主要介紹了vue3實現(xiàn)點擊空白區(qū)域隱藏div方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • vue選項卡Tabs組件實現(xiàn)示例詳解

    vue選項卡Tabs組件實現(xiàn)示例詳解

    這篇文章主要為大家介紹了vue選項卡Tabs組件實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • vue實例中data使用return包裹的方法

    vue實例中data使用return包裹的方法

    今天小編就為大家分享一篇vue實例中data使用return包裹的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Vuejs實現(xiàn)購物車功能

    Vuejs實現(xiàn)購物車功能

    這篇文章主要為大家詳細介紹了Vuejs實現(xiàn)購物車功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Element-Ui組件 NavMenu 導(dǎo)航菜單的具體使用

    Element-Ui組件 NavMenu 導(dǎo)航菜單的具體使用

    這篇文章主要介紹了Element-Ui組件 NavMenu 導(dǎo)航菜單的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 在vue中使用echarts實現(xiàn)上浮與下鉆效果

    在vue中使用echarts實現(xiàn)上浮與下鉆效果

    這篇文章主要介紹了在vue中使用echarts實現(xiàn)上浮與下鉆效果,本文分步驟給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • Vue實現(xiàn)父子組件傳值其實不難

    Vue實現(xiàn)父子組件傳值其實不難

    這篇文章主要介紹了Vue實現(xiàn)父子組件傳值其實不難問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評論