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

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

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

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

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

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

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

在js中,我們使用Object.defineProperty()和ES6的proxy來(lái)對(duì)對(duì)象進(jìn)行偵測(cè)

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

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,每當(dāng)從data中的key中讀取數(shù)據(jù)的時(shí)候觸發(fā)get,修改的數(shù)據(jù)的時(shí)候觸發(fā)set

(2)依賴收集

先收集依賴,等到屬性發(fā)生改變的時(shí)候,再把收集到的依賴循環(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)遞歸偵測(cè)所有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類就是將對(duì)象的所有屬性變?yōu)轫憫?yīng)式的

2.Array的變化偵測(cè)

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

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto);
//和數(shù)組原型一樣的對(duì)象作為攔截器
['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

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

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

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

__ob__是不可枚舉屬性,這個(gè)屬性的值就是當(dāng)前Observer實(shí)例

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

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

this.__ob__.dep.notify();

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

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

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

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

通過(guò)攔截push,unshift,splice等方法,并且把a(bǔ)rgs存儲(chǔ)在inserted中

if(inserted) ob.observeArray(inserted)

總結(jié):

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

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

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

相關(guān)文章

  • Vue3數(shù)字滾動(dòng)插件vue-countup-v3的使用

    Vue3數(shù)字滾動(dòng)插件vue-countup-v3的使用

    vue-countup-v3 插件是一個(gè)基于 Vue3 的數(shù)字動(dòng)畫(huà)插件,用于在網(wǎng)站或應(yīng)用程序中創(chuàng)建帶有數(shù)字動(dòng)畫(huà)效果的計(jì)數(shù)器,本文主要介紹了Vue3數(shù)字滾動(dòng)插件vue-countup-v3的使用,感興趣的可以了解一下
    2023-10-10
  • vue中watch監(jiān)聽(tīng)器用法之deep、immediate、flush

    vue中watch監(jiān)聽(tīng)器用法之deep、immediate、flush

    Vue是可以監(jiān)聽(tīng)到多層級(jí)數(shù)據(jù)改變的,且可以在頁(yè)面上做出對(duì)應(yīng)展示,下面這篇文章主要給大家介紹了關(guān)于vue中watch監(jiān)聽(tīng)器用法之deep、immediate、flush的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • 深入解析vue 源碼目錄及構(gòu)建過(guò)程分析

    深入解析vue 源碼目錄及構(gòu)建過(guò)程分析

    這篇文章主要介紹了vue 源碼目錄及構(gòu)建過(guò)程分析,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-04-04
  • Vue2?特殊符號(hào)讓人傻傻分不清?“:”、“.”、“@”、“#”?、“{{}}“?、“$“,‘$bus‘,‘$event‘

    Vue2?特殊符號(hào)讓人傻傻分不清?“:”、“.”、“@”、“#”?、“{{}}“?、“$“,‘$bus‘,‘$e

    :”是指令?“v-bind”的縮寫(xiě)“.”是修飾符?“@”是指令“v-on”的縮寫(xiě)?,它用于監(jiān)聽(tīng)?DOM?事件?“#”是v-slot的縮寫(xiě),這篇文章主要介紹了Vue2?新手上路無(wú)處不在的特殊符號(hào)讓人傻傻分不清“:”、“.”、“@”、“#”?、“{{}}“?、“$“,$bus,$event,需要的朋友可以參考下
    2024-08-08
  • Vue.js組件使用props傳遞數(shù)據(jù)的方法

    Vue.js組件使用props傳遞數(shù)據(jù)的方法

    這篇文章主要為大家詳細(xì)介紹了Vue.js組件使用props傳遞數(shù)據(jù)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • vue?Element?UI擴(kuò)展內(nèi)容過(guò)長(zhǎng)使用tooltip顯示

    vue?Element?UI擴(kuò)展內(nèi)容過(guò)長(zhǎng)使用tooltip顯示

    這篇文章主要為大家介紹了vue?Element?UI擴(kuò)展內(nèi)容過(guò)長(zhǎng)使用tooltip展示鼠標(biāo)hover時(shí)的提示信息,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Vue讓router-view默認(rèn)顯示頁(yè)面操作方法

    Vue讓router-view默認(rèn)顯示頁(yè)面操作方法

    一個(gè)home頁(yè)面,點(diǎn)擊左邊的菜單欄,右邊顯示頁(yè)面,因此都知道在右邊放一個(gè)router-view然后配置路由即可,然而問(wèn)題出現(xiàn)在:重新打開(kāi)的時(shí)候,默認(rèn)是白色空的,遇到這樣的問(wèn)題如何解決呢,下面小編給大家分享Vue讓router-view默認(rèn)顯示頁(yè)面操作方法,感興趣的朋友一起看看吧
    2024-03-03
  • uniapp實(shí)現(xiàn)省市區(qū)三級(jí)級(jí)聯(lián)選擇功能(含地區(qū)json文件)

    uniapp實(shí)現(xiàn)省市區(qū)三級(jí)級(jí)聯(lián)選擇功能(含地區(qū)json文件)

    這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)省市區(qū)三級(jí)級(jí)聯(lián)選擇功能(含地區(qū)json文件)的相關(guān)資料,級(jí)級(jí)聯(lián)是一種常見(jiàn)的網(wǎng)頁(yè)交互設(shè)計(jì),用于省市區(qū)選擇,它的目的是方便用戶在一系列選項(xiàng)中進(jìn)行選擇,并且確保所選選項(xiàng)的正確性和完整性,需要的朋友可以參考下
    2024-06-06
  • vue生成文件本地打開(kāi)查看效果的實(shí)例

    vue生成文件本地打開(kāi)查看效果的實(shí)例

    今天小編就為大家分享一篇vue生成文件本地打開(kāi)查看效果的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • this.$router.push攜帶參數(shù)跳轉(zhuǎn)頁(yè)面的實(shí)現(xiàn)代碼

    this.$router.push攜帶參數(shù)跳轉(zhuǎn)頁(yè)面的實(shí)現(xiàn)代碼

    這篇文章主要介紹了this.$router.push攜帶參數(shù)跳轉(zhuǎn)頁(yè)面,this.$router.push進(jìn)行頁(yè)面跳轉(zhuǎn)時(shí),攜帶參數(shù)有params和query兩種方式,本文結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下
    2023-04-04

最新評(píng)論

河源市| 南漳县| 三都| 嘉兴市| 横山县| 姜堰市| 垣曲县| 祁阳县| 云阳县| 罗定市| 扶余县| 平罗县| 凌海市| 乌鲁木齐市| 眉山市| 察隅县| 湖南省| 安远县| 天镇县| 龙川县| 许昌县| 平舆县| 贡嘎县| 荆州市| 申扎县| 太原市| 西和县| 海门市| 右玉县| 卢湾区| 响水县| 怀来县| 巩义市| 凤庆县| 东阿县| 日喀则市| 西安市| 朝阳市| 滁州市| 苏尼特左旗| 大渡口区|