久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

關(guān)于vue中如何監(jiān)聽數(shù)組變化

瀏覽:4日期:2022-09-30 13:00:50
前言

前段時(shí)間學(xué)習(xí)了關(guān)于vue中響應(yīng)式數(shù)據(jù)的原理,(并作了學(xué)習(xí)筆記vue響應(yīng)式原理),其實(shí)是通過Object.defineProperty控制getter和setter,并利用觀察者模式完成的響應(yīng)式設(shè)計(jì)。那么數(shù)組有一系列的操作方法,這些方法并不會(huì)觸發(fā)數(shù)組的getter和setter方法。那么vue中針對(duì)數(shù)組的響應(yīng)式設(shè)計(jì)是如何實(shí)現(xiàn)的呢...那么我們一起去學(xué)習(xí)下吧~

源碼部分

https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js

從哪開始第一步學(xué)習(xí)呢

Emmmm...我覺得要先把Vue中的數(shù)據(jù)響應(yīng)式原理弄清楚,這樣對(duì)于理解vue中是如何檢測(cè)數(shù)組的變化才比較好,所以,可以去網(wǎng)上找下文章然后配合源碼進(jìn)行閱讀,相信你一定會(huì)理解的。推薦下我之前看的一篇博客,還有我看過后自己寫的學(xué)習(xí)記錄吧,哈哈。

vue響應(yīng)式原理

vue的雙向綁定原理和實(shí)現(xiàn)

好的,先看看這個(gè)吧。哈哈!

從圖開始

咱們先看下下面的圖,先了解下vue中實(shí)現(xiàn)的思路,這樣接下來(lái)再看源碼的實(shí)現(xiàn),會(huì)一清二楚,明明白白。

關(guān)于vue中如何監(jiān)聽數(shù)組變化

看到這個(gè)圖然后思考一下,是不是大致了解了~

首先判斷瀏覽器是否支持__proto__指針

重寫數(shù)組的這7個(gè)方法,然后根據(jù)是否支持__proto__,將改寫后的數(shù)組指向數(shù)組的prototype。

是不是很簡(jiǎn)單!!!

看看源碼吧

了解了實(shí)現(xiàn)原理,那么我們?cè)倏纯丛创a吧,看下源碼主要是更深入的了解作者是如何實(shí)現(xiàn)的,也可以看下優(yōu)秀的代碼編碼方式,加以學(xué)習(xí)。

關(guān)于一些解釋我就寫在下面的代碼塊中了哈!

//https://github.com/vuejs/vue/blob/dev/src/core/observer/array.js//def方法是基于Object.defineProperty封裝的一層方法,很簡(jiǎn)單,我會(huì)在下面把代碼貼出來(lái),免得大家去找了。import { def } from ’../util/index’ //保存下原生的數(shù)組原型對(duì)象const arrayProto = Array.prototype//進(jìn)行原型連接,將arrayMethods的原型指向Array.prototypeexport const arrayMethods = Object.create(arrayProto)const methodsToPatch = [ ’push’, ’pop’, ’shift’, ’unshift’, ’splice’, ’sort’, ’reverse’]methodsToPatch.forEach(function (method) { // 緩存原生的方法 const original = arrayProto[method] def(arrayMethods, method, function mutator (...args) { var args = [], len = arguments.length; while (len--) args[len] = arguments[len]; const result = original.apply(this, args) // 原來(lái)的數(shù)組方法執(zhí)行結(jié)果 const ob = this.__ob__ // 這個(gè)__ob__就是Observe的實(shí)例~~~~ let inserted switch (method) { case ’push’: case ’unshift’:inserted = argsbreak case ’splice’:inserted = args.slice(2)break } if (inserted) ob.observeArray(inserted) // 如果數(shù)組有變化,則重新調(diào)用observeArray // notify change ob.dep.notify() // return result })})

這個(gè)是關(guān)于Observe的代碼:

var Observer = function Observer(value) { this.value = value; this.dep = new Dep(); this.vmCount = 0; def(value, ’__ob__’, this); //這里會(huì)看到在每個(gè)對(duì)象數(shù)據(jù)上都會(huì)綁定一個(gè)Observe的實(shí)例,所以上面代碼中的this.__ob__就是這個(gè) if (Array.isArray(value)) { // 這里判斷是否是數(shù)組類型的數(shù)據(jù),如果是的話就走observeArray if (hasProto) {protoAugment(value, arrayMethods); } else {copyAugment(value, arrayMethods, arrayKeys); } this.observeArray(value); //這里就是處理數(shù)組類型的數(shù)據(jù),如下 } else { this.walk(value); } };

如下是observeArray的實(shí)現(xiàn):

Observer.prototype.observeArray = function observeArray(items) { for (var i = 0, l = items.length; i < l; i++) { observe(items[i]); // 這個(gè)observe方法如下 } };

在這里我們看下observe這個(gè)方法:

function observe(value, asRootData) { if (!isObject(value) || value instanceof VNode) { return } var ob; if (hasOwn(value, ’__ob__’) && value.__ob__ instanceof Observer) { ob = value.__ob__; } else if ( shouldObserve && !isServerRendering() && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue ) { ob = new Observer(value); } if (asRootData && ob) { ob.vmCount++; } return ob }

這個(gè)是關(guān)于def方法的實(shí)現(xiàn),很簡(jiǎn)單我就不說(shuō)了哈:

function def (obj, key, val, enumerable) { Object.defineProperty(obj, key, { value: val, enumerable: !!enumerable, writable: true, configurable: true });}

以上就是關(guān)于vue中如何監(jiān)聽數(shù)組變化的詳細(xì)內(nèi)容,更多關(guān)于vue如何監(jiān)聽數(shù)組的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Vue
相關(guān)文章:
主站蜘蛛池模板: 迁西县| 金湖县| 福州市| 滦平县| 通许县| 拜城县| 香河县| 定边县| 祥云县| 娄底市| 敖汉旗| 武安市| 浏阳市| 阜城县| 张家界市| 卓资县| 怀远县| 阿拉尔市| 麻城市| 乐都县| 仙居县| 钟山县| 东兴市| 武安市| 临西县| 泽普县| 兴海县| 天柱县| 大余县| 昌都县| 叶城县| 淮滨县| 东安县| 东城区| 思茅市| 碌曲县| 瓮安县| 日土县| 烟台市| 丹凤县| 青岛市|