1. v-model原理
雙向綁定原理
實(shí)現(xiàn)原理數(shù)據(jù)劫持+發(fā)布者+訂閱者
① 對vue中所有屬性使用Object.defineProperty()
進(jìn)行數(shù)據(jù)劫持抵赢,并為每個(gè)屬性分配發(fā)布者Dep數(shù)組欺劳,
② 然后在編譯的時(shí)候,給這個(gè)發(fā)布者數(shù)組添加訂閱者铅鲤,v-model會加個(gè)訂閱者划提,v-bind也會,所有用到這個(gè)屬性的都會添加一個(gè)訂閱者;
③ 再給這個(gè)屬性添加監(jiān)聽邢享,當(dāng)監(jiān)聽到屬性發(fā)生變化的時(shí)候鹏往,就會使用Object.defineProperty()
的set方法來修改屬性,然后將變化通知給發(fā)布者骇塘,發(fā)布者再循環(huán)去調(diào)用訂閱者的update方法更新到視圖上伊履。
MVVM的進(jìn)化史:MVC -> MVP -> MVVM
MVC:M(model模型)、V(view視圖)款违、C(controller控制器)唐瀑,M可以理解為后端傳過來的數(shù)據(jù),V可以理解為前端頁面奠货,C就是我們給dom元素添加的事件也就是邏輯代碼介褥;它們?nèi)齻€(gè)間數(shù)據(jù)是單向的,也就是M發(fā)生變化了就立即通知V,V發(fā)生變化了就通知C然后給M柔滔,M和V的直接交互導(dǎo)致對dom的頻繁操作溢陪,降低了性能,所以出現(xiàn)了MVP睛廊;
MVP:M(model模型)形真、V(view視圖)、P(Presenter發(fā)布層)超全,為了實(shí)現(xiàn)頁面和數(shù)據(jù)邏輯分離咆霜,所以出現(xiàn)了MVP,實(shí)現(xiàn)了M與P之間嘶朱、V與P之間的數(shù)據(jù)雙向傳遞蛾坯,即所有的交互都發(fā)生在P那,避免了M與V直接交互疏遏;為了實(shí)現(xiàn)雙向綁定所以出現(xiàn)了MVVM
MVVM:的出現(xiàn)既減少了對DOM的操作又實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定脉课;M(model模型)、V(view視圖)财异、VM(viewModel視圖模型倘零,是C和P的合體),VM是MVVM的核心戳寸,它有2個(gè)方向:① 視圖更改模型呈驶,利用DOM事件監(jiān)聽;② 模型更改視圖疫鹊,利用數(shù)據(jù)綁定
2. diff算法
瀏覽器的運(yùn)行機(jī)制:
構(gòu)建dom樹 -> 構(gòu)建渲染樹 -> 布局渲染樹 -> 繪制渲染樹
重排:渲染樹重新構(gòu)建袖瞻,比如修改dom尺寸、位置订晌、新增虏辫、刪除dom都會使瀏覽器重新構(gòu)建渲染樹;
重繪:部分dom僅外觀發(fā)生變化锈拨,比如顏色、字體大小等羹唠,瀏覽器會根據(jù)這個(gè)元素的新屬性重新繪制奕枢;
重排一定會引起重繪,但是重繪不一定會引起重排
如果每修改一個(gè)dom佩微,就引起整顆樹的重繪和重排缝彬,非常影響性能,所以出現(xiàn)了diff算法哺眯。
diff算法是對2個(gè)虛擬dom樹進(jìn)行同層級一一對比谷浅,如果有差異就以新的為準(zhǔn),然后插入到真是dom中,重新渲染一疯。v-for中寫Key也是用的這個(gè)原理撼玄,為了能更快速的找到有差異的那個(gè)元素,不寫key的話就會進(jìn)行頭尾兩端的相互比較墩邀。
3. v-for掌猛、v-if優(yōu)先級
v-for比v-if優(yōu)先級高,因此v-for和v-if一起使用的時(shí)候眉睹,數(shù)組的每一項(xiàng)都要執(zhí)行v-if語句荔茬,所以建議把v-if寫在template或外層元素上。
4. vue-router hash竹海、history區(qū)別
vue-router的出現(xiàn)是為了防止頁面改變的同時(shí)向后端發(fā)送請求慕蔚。
hash模式:url后面會跟個(gè)#,而且這個(gè)#不會跟在請求的url后面斋配,所以對后端沒有影響坊萝;
history模式:url后面沒有#,但是需要后端支持比如nginx需要配置try_files(將頁面重定向到首頁)许起,不然會出現(xiàn)刷新二級頁面顯示404(因?yàn)樗⑿马撁鏁r(shí)會訪問真實(shí)路由)十偶,hitory是利用html5新增的兩個(gè)方法history.pushState
、history.replaceState
這2個(gè)方法园细,只會使history對象發(fā)生變化惦积,從而改變地址欄的url,不會向后端發(fā)送請求猛频。
history和hash都是利用瀏覽器的特性來實(shí)現(xiàn)的狮崩。
路由守衛(wèi):
router.beforeEach
有三個(gè)參數(shù):to(去哪兒)、from(正要離開的路由)鹿寻、next(是個(gè)函數(shù)睦柴,調(diào)用next就可以進(jìn)入路由)≌毖可以在里面做一些操作坦敌,比如驗(yàn)證token是否存在、路由是否存在痢法、是否有權(quán)限訪問這個(gè)頁面狱窘。
5. render、jsx區(qū)別
總結(jié):
render使用createElement創(chuàng)建元素蘸炸,有三個(gè)參數(shù)標(biāo)簽名、屬性對象尖奔、子組件數(shù)組搭儒,寫起來繁瑣且不直觀穷当;
jsx可以直接寫html標(biāo)簽,babel會將jsx轉(zhuǎn)成render
6. 自定義指令鉤子函數(shù)
5個(gè)鉤子函數(shù):
bind:只調(diào)用一次淹禾,指令第一次綁定到元素上的時(shí)候調(diào)用馁菜;
inserted:元素插入到父元素上的時(shí)候調(diào)用;
update:當(dāng)前組件更新時(shí)調(diào)用稀拐,不管子組件是否更新火邓;
componentUpdated:當(dāng)前組件和子組件更新完成后調(diào)用;
unbind:解綁德撬,只調(diào)用一次铲咨。
四個(gè)參數(shù):
el(指令綁定的元素)、binding(一個(gè)對象蜓洪,里面有很多值)纤勒、vnode(虛擬節(jié)點(diǎn))、oldVnode(上一個(gè)虛擬節(jié)點(diǎn)隆檀,僅在 update 和 componentUpdated 鉤子中可用)
除了 el 之外摇天,其它參數(shù)都應(yīng)該是只讀的,切勿進(jìn)行修改恐仑。
如果想修改value泉坐,可以dom.dispatchEvent(new Event('input'));
調(diào)用input事件使vue v-model綁定更新