电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

vue中是怎樣監(jiān)聽數(shù)組變化的

瀏覽:130日期:2022-11-13 10:50:20

我們知道通過Object.defineProperty()劫持?jǐn)?shù)組為其設(shè)置getter和setter后,調(diào)用的數(shù)組的push、splice、pop等方法改變數(shù)組元素時(shí)并不會(huì)觸發(fā)數(shù)組的setter,這就會(huì)造成使用上述方法改變數(shù)組后,頁(yè)面上并不能及時(shí)體現(xiàn)這些變化,也就是數(shù)組數(shù)據(jù)變化不是響應(yīng)式的(對(duì)上述不了解的可以參考這篇文章)。但實(shí)際用vue開發(fā)時(shí),對(duì)于響應(yīng)式數(shù)組,使用push、splice、pop等方法改變數(shù)組時(shí),頁(yè)面會(huì)及時(shí)體現(xiàn)這種變化,那么vue中是如何實(shí)現(xiàn)的呢?

通過vue源碼可以看出,vue重寫了數(shù)組的push、splice、pop等方法。

// src/core/observer/array.js// 獲取數(shù)組的原型Array.prototype,上面有我們常用的數(shù)組方法const arrayProto = Array.prototype// 創(chuàng)建一個(gè)空對(duì)象arrayMethods,并將arrayMethods的原型指向Array.prototypeexport const arrayMethods = Object.create(arrayProto)// 列出需要重寫的數(shù)組方法名const methodsToPatch = [ ’push’, ’pop’, ’shift’, ’unshift’, ’splice’, ’sort’, ’reverse’]// 遍歷上述數(shù)組方法名,依次將上述重寫后的數(shù)組方法添加到arrayMethods對(duì)象上methodsToPatch.forEach(function (method) { // 保存一份當(dāng)前的方法名對(duì)應(yīng)的數(shù)組原始方法 const original = arrayProto[method] // 將重寫后的方法定義到arrayMethods對(duì)象上,function mutator() {}就是重寫后的方法 def(arrayMethods, method, function mutator (...args) { // 調(diào)用數(shù)組原始方法,并傳入?yún)?shù)args,并將執(zhí)行結(jié)果賦給result const result = original.apply(this, args) // 當(dāng)數(shù)組調(diào)用重寫后的方法時(shí),this指向該數(shù)組,當(dāng)該數(shù)組為響應(yīng)式時(shí),就可以獲取到其__ob__屬性 const ob = this.__ob__ let inserted switch (method) { case ’push’: case ’unshift’: inserted = args break case ’splice’: inserted = args.slice(2) break } if (inserted) ob.observeArray(inserted) // 將當(dāng)前數(shù)組的變更通知給其訂閱者 ob.dep.notify() // 最后返回執(zhí)行結(jié)果result return result })})

從上面可以看出array.js中重寫了數(shù)組的push、pop、shift、unshift、splice、sort、reverse七種方法,重寫方法在實(shí)現(xiàn)時(shí)除了將數(shù)組方法名對(duì)應(yīng)的原始方法調(diào)用一遍并將執(zhí)行結(jié)果返回外,還通過執(zhí)行ob.dep.notify()將當(dāng)前數(shù)組的變更通知給其訂閱者,這樣當(dāng)使用重寫后方法改變數(shù)組后,數(shù)組訂閱者會(huì)將這邊變化更新到頁(yè)面中。

重寫完數(shù)組的上述7種方法外,我們還需要將這些重寫的方法應(yīng)用到數(shù)組上,因此在Observer構(gòu)造函數(shù)中,可以看到在監(jiān)聽數(shù)據(jù)時(shí)會(huì)判斷數(shù)據(jù)類型是否為數(shù)組。當(dāng)為數(shù)組時(shí),如果瀏覽器支持__proto__,則直接將當(dāng)前數(shù)據(jù)的原型__proto__指向重寫后的數(shù)組方法對(duì)象arrayMethods,如果瀏覽器不支持__proto__,則直接將arrayMethods上重寫的方法直接定義到當(dāng)前數(shù)據(jù)對(duì)象上;當(dāng)數(shù)據(jù)類型為非數(shù)組時(shí),繼續(xù)遞歸執(zhí)行數(shù)據(jù)的監(jiān)聽。

// src/core/observer/index.jsexport class Observer { ... constructor (value: any) { this.value = value this.dep = new Dep() this.vmCount = 0 def(value, ’__ob__’, this) if (Array.isArray(value)) { if (hasProto) { protoAugment(value, arrayMethods) } else { copyAugment(value, arrayMethods, arrayKeys) } this.observeArray(value) } else { this.walk(value) } } ...}function protoAugment (target, src: Object) { /* eslint-disable no-proto */ target.__proto__ = src /* eslint-enable no-proto */}function copyAugment (target: Object, src: Object, keys: Array<string>) { for (let i = 0, l = keys.length; i < l; i++) { const key = keys[i] def(target, key, src[key]) }}

經(jīng)過上述處理后,對(duì)于數(shù)組,當(dāng)我們調(diào)用其方法處理數(shù)組時(shí)會(huì)按照如下原型鏈來獲取數(shù)組方法:

vue中是怎樣監(jiān)聽數(shù)組變化的

對(duì)于響應(yīng)式數(shù)組,當(dāng)瀏覽器支持__proto__屬性時(shí),使用push等方法時(shí)先從其原型arrayMethods上尋找push方法,也就是重寫后的方法,處理之后數(shù)組的變化會(huì)通知到其訂閱者,更新頁(yè)面,當(dāng)在arrayMethods上查詢不到時(shí)會(huì)向上在Array.prototype上查詢;當(dāng)瀏覽器不支持__proto__屬性時(shí),使用push等方法時(shí)會(huì)先從數(shù)組自身上查詢,如果查詢不到會(huì)向上再Array.prototype上查詢。

對(duì)于非響應(yīng)式數(shù)組,當(dāng)使用push等方法時(shí)會(huì)直接從Array.prototype上查詢。

值得一提的是源碼中通過判斷瀏覽器是否支持__proto__來分別使用protoAugment和copyAugment 方法將重寫后的數(shù)組方法應(yīng)用到數(shù)組中,這是因?yàn)閷?duì)于IE10及以下的IE瀏覽器是不支持__proto__屬性的:

上述截圖參考于Vue源碼解析五——數(shù)據(jù)響應(yīng)系統(tǒng)

結(jié)論:

在將數(shù)組處理成響應(yīng)式數(shù)據(jù)后,如果使用數(shù)組原始方法改變數(shù)組時(shí),數(shù)組值會(huì)發(fā)生變化,但是并不會(huì)觸發(fā)數(shù)組的setter來通知所有依賴該數(shù)組的地方進(jìn)行更新,為此,vue通過重寫數(shù)組的某些方法來監(jiān)聽數(shù)組變化,重寫后的方法中會(huì)手動(dòng)觸發(fā)通知該數(shù)組的所有依賴進(jìn)行更新。

如果我的內(nèi)容能對(duì)你有所幫助,我就很開心啦!

以上就是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)文章:
主站蜘蛛池模板: 包装机_厂家_价格-山东包装机有限公司 | 二次元影像仪|二次元测量仪|拉力机|全自动影像测量仪厂家_苏州牧象仪器 | 无尘烘箱_洁净烤箱_真空无氧烤箱_半导体烤箱_电子防潮柜-深圳市怡和兴机电 | YT保温材料_YT无机保温砂浆_外墙保温材料_南阳银通节能建材高新技术开发有限公司 | 行业分析:提及郑州火车站附近真有 特殊按摩 ?2025实地踩坑指南 新手如何避坑不踩雷 | 芝麻黑-芝麻黑石材厂家-永峰石业 | 自动化生产线-自动化装配线-直流电机自动化生产线-东莞市慧百自动化有限公司 | 低噪声电流前置放大器-SR570电流前置放大器-深圳市嘉士达精密仪器有限公司 | 棉服定制/厂家/公司_棉袄订做/价格/费用-北京圣达信棉服 | 日本细胞免疫疗法_肿瘤免疫治疗_NK细胞疗法 - 免疫密码 | 蓝莓施肥机,智能施肥机,自动施肥机,水肥一体化项目,水肥一体机厂家,小型施肥机,圣大节水,滴灌施工方案,山东圣大节水科技有限公司官网17864474793 | 欧洲MV日韩MV国产_人妻无码一区二区三区免费_少妇被 到高潮喷出白浆av_精品少妇自慰到喷水AV网站 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 磁棒电感生产厂家-电感器厂家-电感定制-贴片功率电感供应商-棒形电感生产厂家-苏州谷景电子有限公司 | 查分易-成绩发送平台官网 | 成都LED显示屏丨室内户外全彩led屏厂家方案报价_四川诺显科技 | 制冷采购电子商务平台——制冷大市场| 上海办公室装修公司_办公室设计_直营办公装修-羚志悦装 | 剪刃_纵剪机刀片_分条机刀片-南京雷德机械有限公司 | HDPE土工膜,复合土工膜,防渗膜价格,土工膜厂家-山东新路通工程材料有限公司 | 模具ERP_模具管理系统_模具mes_模具进度管理_东莞市精纬软件有限公司 | 数年网路-免费在线工具您的在线工具箱-shuyear.com | 无线遥控更衣吊篮_IC卡更衣吊篮_电动更衣吊篮配件_煤矿更衣吊篮-力得电子 | 废气处理设备-工业除尘器-RTO-RCO-蓄热式焚烧炉厂家-江苏天达环保设备有限公司 | 糖衣机,除尘式糖衣机,全自动糖衣机,泰州市长江制药机械有限公司 体感VRAR全息沉浸式3D投影多媒体展厅展会游戏互动-万展互动 | 翰香原枣子坊加盟费多少钱-正宗枣核糕配方培训利润高飘香 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 车载加油机品牌_ 柴油加油机厂家| TPE_TPE热塑性弹性体_TPE原料价格_TPE材料厂家-惠州市中塑王塑胶制品公司- 中塑王塑胶制品有限公司 | 余姚生活网_余姚论坛_余姚市综合门户网站 | 聚氨酯复合板保温板厂家_廊坊华宇创新科技有限公司 | 深圳市简易检测技术有限公司| 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! | 棕刚玉-白刚玉厂家价格_巩义市东翔净水材料厂 | 巨野月嫂-家政公司-巨野县红墙安康母婴护理中心 | 六自由度平台_六自由度运动平台_三自由度摇摆台—南京全控科技 | 一体式钢筋扫描仪-楼板测厚仪-裂缝检测仪-泰仕特(北京) | 广东佛电电器有限公司|防雷开关|故障电弧断路器|智能量测断路器 广东西屋电气有限公司-广东西屋电气有限公司 | WTB5光栅尺-JIE WILL磁栅尺-B60数显表-常州中崴机电科技有限公司 | 防爆电机生产厂家,YBK3电动机,YBX3系列防爆电机,YBX4节防爆电机--河南省南洋防爆电机有限公司 | 深圳公司注册-工商注册公司-千百顺代理记账公司 |