寫在前面的話
面多了庞瘸,問題五花八門捧弃,但也有一些規(guī)律,比如擦囊,今兒的題就是澄ハ迹考題~
(一)Vue的雙向綁定原理
實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,首先要對(duì)數(shù)據(jù)進(jìn)行劫持監(jiān)聽瞬场,所以我們需要設(shè)置一個(gè)監(jiān)聽器Observer买鸽,用來監(jiān)聽所有屬性。如果屬性發(fā)上變化了泌类,就需要告訴訂閱者Watcher看是否需要更新癞谒。因?yàn)橛嗛喺呤怯泻芏鄠€(gè)底燎,所以我們需要有一個(gè)消息訂閱器Dep來專門收集這些訂閱者,然后在監(jiān)聽器Observer和訂閱者Watcher之間進(jìn)行統(tǒng)一管理的弹砚。接著双仍,我們還需要有一個(gè)指令解析器Compile,對(duì)每個(gè)節(jié)點(diǎn)元素進(jìn)行掃描和解析桌吃,將相關(guān)指令對(duì)應(yīng)初始化成一個(gè)訂閱者Watcher朱沃,并替換模板數(shù)據(jù)或者綁定相應(yīng)的函數(shù),此時(shí)當(dāng)訂閱者Watcher接收到相應(yīng)屬性的變化茅诱,就會(huì)執(zhí)行對(duì)應(yīng)的更新函數(shù)逗物,從而更新視圖。因此接下去我們執(zhí)行以下3個(gè)步驟瑟俭,實(shí)現(xiàn)數(shù)據(jù)的雙向綁定:
1.實(shí)現(xiàn)一個(gè)監(jiān)聽器Observer翎卓,用來劫持并監(jiān)聽所有屬性,如果有變動(dòng)的摆寄,就通知訂閱者失暴。
2.實(shí)現(xiàn)一個(gè)訂閱者Watcher,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù)微饥,從而更新視圖逗扒。
3.實(shí)現(xiàn)一個(gè)解析器Compile,可以掃描和解析每個(gè)節(jié)點(diǎn)的相關(guān)指令欠橘,并根據(jù)初始化模板數(shù)據(jù)以及初始化相應(yīng)的訂閱器矩肩。
vm.$set()原理
受現(xiàn)代 JavaScript 的限制 (而且 Object.observe 也已經(jīng)被廢棄),Vue 無法檢測(cè)到對(duì)象屬性的添加或刪除肃续。由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì)屬性執(zhí)行 getter/setter 轉(zhuǎn)化黍檩,所以屬性必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的。
對(duì)于已經(jīng)創(chuàng)建的實(shí)例痹升,Vue 不允許動(dòng)態(tài)添加根級(jí)別的響應(yīng)式屬性建炫。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套對(duì)象添加響應(yīng)式屬性疼蛾。
vm.$set()在new Vue()時(shí)候就被注入到Vue的原型上肛跌。
vm.$set()解決了什么問題? 避免濫用
在Vue.js里面只有data中已經(jīng)存在的屬性才會(huì)被Observe為響應(yīng)式數(shù)據(jù), 如果你是新增的屬性是不會(huì)成為響應(yīng)式數(shù)據(jù), 因此Vue提供了一個(gè)api(vm.$set)來解決這個(gè)問題。
數(shù)據(jù)響應(yīng)式原理
vue數(shù)據(jù)雙向綁定是通過數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來實(shí)現(xiàn)的察郁,
那么vue是如果進(jìn)行數(shù)據(jù)劫持的衍慎??皮钠?
1)vue2.0版本是利用了Object.defineProperty()這個(gè)方法重新定義對(duì)象獲取屬性值的get和設(shè)置屬性值set的操作來實(shí)現(xiàn)的稳捆。
2)vue3.0版本采用了Es6的Proxy對(duì)象來實(shí)現(xiàn)。
Object.defineProperty的缺點(diǎn) :不能監(jiān)聽到數(shù)組變化
由于 JavaScript 的限制麦轰,Vue 不能檢測(cè)以下變動(dòng)的數(shù)組:
當(dāng)你直接設(shè)置一個(gè)項(xiàng)的索引時(shí), 例如: vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長(zhǎng)度時(shí), 例如: vm.items.length = newLength
無法監(jiān)控到數(shù)組下標(biāo)的變化乔夯,導(dǎo)致直接通過數(shù)組的下標(biāo)給數(shù)組設(shè)置值砖织,不能實(shí)時(shí)響應(yīng)。
https://www.cnblogs.com/YikaJ/p/4278255.html
所以vue才設(shè)置了7個(gè)變異數(shù)組(push末荐、pop侧纯、shift、unshift甲脏、splice眶熬、sort、reverse)的 hack 方法來解決問題块请。
只能劫持對(duì)象的屬性,因此我們需要對(duì)每個(gè)對(duì)象的每個(gè)屬性進(jìn)行遍歷娜氏。如果能直接劫持一個(gè)對(duì)象,就不需要遞歸 + 遍歷了
為什么vue3中改用proxy
1)defineProperty只能監(jiān)聽某個(gè)屬性墩新,不能對(duì)全對(duì)象監(jiān)聽贸弥,所以可以省去for in 提升效率
2)可以監(jiān)聽數(shù)組,不用再去單獨(dú)對(duì)數(shù)組做操作
3)Proxy只是代理了原對(duì)象抖棘,不會(huì)污染原對(duì)象
那么茂腥,在vue中從一個(gè)數(shù)據(jù)到發(fā)生改變的過程是什么?
MVVM和MVC的區(qū)別
MVC全名是Model View Controller切省,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設(shè)計(jì)典范帕胆,用一種業(yè)務(wù)邏輯朝捆、數(shù)據(jù)、界面顯示分離的方法組織代碼懒豹,將業(yè)務(wù)邏輯聚集到一個(gè)部件里面芙盘,在改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí),不需要重新編寫業(yè)務(wù)邏輯脸秽。MVC被獨(dú)特的發(fā)展起來用于映射傳統(tǒng)的輸入儒老、處理和輸出功能在一個(gè)邏輯的圖形化用戶界面的結(jié)構(gòu)中。
幾乎所有的App都只干這么一件事:將數(shù)據(jù)展示給用戶看记餐,并處理用戶對(duì)界面的操作驮樊。
MVC的思想:一句話描述就是Controller負(fù)責(zé)將Model的數(shù)據(jù)用View顯示出來,換句話說就是在Controller里面把Model的數(shù)據(jù)賦值給View片酝。
MVVM
MVVM:Model囚衔、View、ViewModel雕沿。
你會(huì)下意識(shí)地把它和MVC來對(duì)比练湿,你會(huì)發(fā)現(xiàn),MVVM多了一個(gè)ViewModel而少了Controller审轮。
首先說一下多出來的ViewModel(VM肥哎,不是顯存)辽俗。
VM的意義,和Model一樣篡诽,在于數(shù)據(jù)榆苞。
Model負(fù)責(zé)對(duì)數(shù)據(jù)進(jìn)行取和存,然而我們對(duì)數(shù)據(jù)的操作除了取和存以外霞捡,還有一個(gè)非常重要的操作:解析坐漏。
參考鏈接:
cnblogs.com/renzm0318/p/12289415.html
https://www.cnblogs.com/chenhuichao/p/10818396.html
https://www.cnblogs.com/canfoo/p/6891868.html
http://www.reibang.com/p/77eaaf34e732
https://blog.csdn.net/qq_42068550/article/details/89480350
https://www.cnblogs.com/webcabana/p/11077628.html