對(duì)于MVVM的理解
MVVM是Model-View-ViewModel縮寫篙耗,也就是把MVC中的Controller演變成ViewModel技肩。Model層代表數(shù)據(jù)模型熄赡,View代表UI組件细睡,ViewModel是View和Model層的橋梁裙品,數(shù)據(jù)會(huì)綁定到viewModel層并自動(dòng)將數(shù)據(jù)渲染到頁面中勤揩,視圖變化的時(shí)候會(huì)通知viewModel層更新數(shù)據(jù)咧党。
MVVM 是 Model-View-ViewModel 的縮寫
Model: 代表數(shù)據(jù)模型,也可以在Model中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯陨亡。我們可以把Model稱為數(shù)據(jù)層傍衡,因?yàn)樗鼉H僅關(guān)注數(shù)據(jù)本身,不關(guān)心任何行為
View: 用戶操作界面负蠕。當(dāng)ViewModel對(duì)Model進(jìn)行更新的時(shí)候蛙埂,會(huì)通過數(shù)據(jù)綁定更新到View
ViewModel:業(yè)務(wù)邏輯層,View需要什么數(shù)據(jù)遮糖,ViewModel要提供這個(gè)數(shù)據(jù)绣的;View有某些操作,ViewModel就要響應(yīng)這些操作欲账,所以可以說它是Model for View.
MVVM模式簡化了界面與業(yè)務(wù)的依賴屡江,解決了數(shù)據(jù)頻繁更新。MVVM 在使用當(dāng)中赛不,利用雙向綁定技術(shù)惩嘉,使得 Model 變化時(shí),ViewModel 會(huì)自動(dòng)更新踢故,而 ViewModel 變化時(shí)文黎,View 也會(huì)自動(dòng)變化。
Vue生命周期
vue實(shí)例從創(chuàng)建到銷毀的過程殿较,就是生命周期耸峭。從開始創(chuàng)建、初始化數(shù)據(jù)斜脂、編譯模板抓艳、掛載Dom→渲染、更新→渲染帚戳、銷毀等一系列過程被稱之為vue生命周期玷或。
vue生命周期掛在了很多鉤子函數(shù),我們可以更方便和更有邏輯的控制整個(gè)vue的實(shí)例化的過程
vue生命周期分為八個(gè)階段 創(chuàng)建前/后片任,加載前/后 偏友,更新前/后,銷毀前/后?
頁面第一次加載的時(shí)候 會(huì)觸發(fā)beforeCreate对供、created位他、beforeMount氛濒、mounted這幾個(gè)鉤子,在mounted的時(shí)候會(huì)渲染完成DOM鹅髓。
Vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定的原理:Object.defineProperty()
vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式舞竿,通過?Object.defineProperty()?來劫持各個(gè)屬性的setter,getter窿冯,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者骗奖,觸發(fā)相應(yīng)監(jiān)聽回調(diào)。當(dāng)把一個(gè)普通?Javascript?對(duì)象傳給 Vue 實(shí)例來作為它的?data?選項(xiàng)時(shí)醒串,Vue 將遍歷它的屬性执桌,用?Object.defineProperty()?將它們轉(zhuǎn)為?getter/setter。用戶看不到?getter/setter芜赌,但是在內(nèi)部它們讓?Vue追蹤依賴仰挣,在屬性被訪問和修改時(shí)通知變化。
vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口缠沈,整合Observer膘壶,Compile和Watcher三者,通過Observer來監(jiān)聽自己的model的數(shù)據(jù)變化博烂,通過Compile來解析編譯模板指令(vue中是用來解析?{{}})香椎,最終利用watcher搭起observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 —>視圖更新禽篱;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果畜伐。
Vue組件之間傳遞參數(shù)
父子之間傳遞參數(shù):父組件傳給子組件:子組件通過props方法接受數(shù)據(jù);子組件傳給父組件:$emit?方法傳遞參數(shù)
非父子組件間的數(shù)據(jù)傳遞躺率,兄弟組件傳值? 用eventBus(適合小項(xiàng)目)或者VUEX
Vue路由
路由模式:hash模式 和 history模式
hash模式:在瀏覽器中符號(hào)“#”玛界,#以及#后面的字符稱之為hash,用?window.location.hash?讀取悼吱。特點(diǎn):hash雖然在URL中慎框,但不被包括在HTTP請(qǐng)求中灌旧;用來指導(dǎo)瀏覽器動(dòng)作碟案,對(duì)服務(wù)端安全無用,hash不會(huì)重加載頁面锯蛀。
history模式:history采用HTML5的新特性遇西;且提供了兩個(gè)新方法:pushState()馅精,?replaceState()可以對(duì)瀏覽器歷史記錄棧進(jìn)行修改,以及popState事件的監(jiān)聽到狀態(tài)變更
路由鉤子函數(shù)
全局鉤子函數(shù)(beforeEach粱檀、afterEach)
路由獨(dú)享的鉤子函數(shù)(beforeEnter)
組件內(nèi)鉤子函數(shù)(beforeRouterEnter洲敢、beforeRouterUpdate、beforeRouterLeave)
beforeEach一共接收三個(gè)參數(shù)茄蚯,分別是to压彭、from睦优、next;to:即將進(jìn)入的路由對(duì)象壮不;from:正要離開的路由對(duì)象汗盘;next:路由的控制參數(shù);
AfterEach和beforeEach一樣都是屬于全局守衛(wèi)鉤子忆畅,都是在main.js中進(jìn)行調(diào)用衡未;其中AfterEach比beforeEach少一個(gè)next參數(shù);to:即將要進(jìn)入的路由對(duì)象家凯;from:正要離開的路由對(duì)象;
beforeEneter?指定的路由才有的鉤子函數(shù)如失,通常這類路由獨(dú)享的鉤子函數(shù)我們是在路由配置文件中進(jìn)行配置绊诲,只能設(shè)置改變前的鉤子,不能設(shè)置改變后的鉤子褪贵,只能在設(shè)置的路由 才能觸發(fā)這個(gè)鉤子函數(shù)掂之,其他頁面是不會(huì)觸發(fā)的,也有to,from,next三個(gè)參數(shù)
beforeRouterEnter(to,from,next)是唯一一個(gè)不能使用this的鉤子函數(shù)脆丁,因?yàn)榇藭r(shí)的vue實(shí)例還沒有創(chuàng)建世舰;to:即將要進(jìn)入的路由對(duì)象;from:正要離開的路由對(duì)象槽卫;next:路由控制參數(shù)
beforeRouterUpdate(to,from,next)?在路由發(fā)生修改的時(shí)候進(jìn)行調(diào)用
beforeRouterLeave(to,from,next)?在路由離開該組件時(shí)調(diào)用跟压;
路由之間跳轉(zhuǎn)
<router-link?:to="index"> 或者?router.push('index')
$route和$router的區(qū)別
$route是“路由信息對(duì)象”,包括path歼培,params震蒋,hash,query躲庄,fullPath查剖,matched,name等路由信息參數(shù)噪窘;而$router是“路由實(shí)例”對(duì)象包括了路由的跳轉(zhuǎn)方法笋庄,鉤子函數(shù)等
例如? ?? this.$router.push({
? ? ? ? ? ? ? ?path: "/ems/emsAddPlan",
? ? ? ? ? ? ? ?query: { id: this.$route.query.id }
? ? ? ? ?});
?v-if 和 v-show 區(qū)別
v-if按照條件是否渲染,v-show是display的block或none倔监;
如何讓CSS只在當(dāng)前組件中起作用?
將當(dāng)前組件的<style>修改為<style scoped>
scoped樣式穿透:使用/deep/或者另外寫一個(gè)style樣式 不加scoped
<keep-alive></keep-alive>的作用是什么?
keep-alive可以實(shí)現(xiàn)組件緩存直砂,當(dāng)組件切換時(shí)不會(huì)對(duì)當(dāng)前組件進(jìn)行卸載
<keep-alive></keep-alive>?包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,主要用于保留組件狀態(tài)或避免重新渲染
比如有一個(gè)列表和一個(gè)詳情丐枉,那么用戶就會(huì)經(jīng)常執(zhí)行打開詳情=>返回列表=>打開詳情…這樣的話列表和詳情都是一個(gè)頻率很高的頁面哆键,那么就可以對(duì)列表組件使用<keep-alive></keep-alive>進(jìn)行緩存,這樣用戶每次返回列表的時(shí)候瘦锹,都能從緩存中快速渲染籍嘹,而不是重新渲染
常用的兩個(gè)屬性include/exclude闪盔,允許組件有條件的進(jìn)行緩存
兩個(gè)生命周期activated/deactivated,用來得知當(dāng)前組件是否處于活躍狀態(tài)
指令v-el的作用是什么?
提供一個(gè)在頁面上已存在的?DOM元素作為?Vue實(shí)例的掛載目標(biāo).可以是 CSS 選擇器辱士,也可以是一個(gè)?HTMLElement?實(shí)例
在Vue中使用插件的步驟
采用ES6的import ... from ...語法或CommonJS的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以傳入一個(gè)選項(xiàng)對(duì)象Vue.use(MyPlugin, { someOption: true })
Vue 組件 data 為什么必須是函數(shù)
每個(gè)組件都是?Vue?的實(shí)例泪掀。
組件共享?data?屬性,當(dāng)?data?的值是同一個(gè)引用類型的值時(shí)颂碘,改變其中一個(gè)會(huì)影響其他
Vue computed 實(shí)現(xiàn)
初始化?data异赫, 使用?Object.defineProperty?把這些屬性全部轉(zhuǎn)為?getter/setter。
初始化?computed, 遍歷?computed?里的每個(gè)屬性头岔,每個(gè)?computed?屬性都是一個(gè)?watch?實(shí)例塔拳。每個(gè)屬性提供的函數(shù)作為屬性的?getter,使用?Object.defineProperty?轉(zhuǎn)化峡竣。
Object.defineProperty getter?依賴收集靠抑。用于依賴發(fā)生變化時(shí),觸發(fā)屬性重新計(jì)算适掰。
若出現(xiàn)當(dāng)前?computed?計(jì)算屬性嵌套其他?computed?計(jì)算屬性時(shí)颂碧,先進(jìn)行其他的依賴收集
computed和watch區(qū)別
當(dāng)頁面中有某些數(shù)據(jù)依賴其他數(shù)據(jù)進(jìn)行變動(dòng)的時(shí)候,可以使用計(jì)算屬性computed
watch用于觀察和監(jiān)聽頁面上的vue實(shí)例类浪,如果要在數(shù)據(jù)變化的同時(shí)進(jìn)行異步操作或者是比較大的開銷载城,那么watch為最佳選擇
vue修飾符
stop:阻止事件的冒泡
prevent:阻止事件的默認(rèn)行為
once:只觸發(fā)一次
self:只觸發(fā)自己的事件行為時(shí),才會(huì)執(zhí)行
vue.extend和vue.component
extend是構(gòu)造一個(gè)組件的語法器费就。然后這個(gè)組件你可以作用到Vue.component這個(gè)全局注冊(cè)方法里還可以在任意vue模板里使用組件诉瓦。也可以作用到vue實(shí)例或者某個(gè)組件中的components屬性中并在內(nèi)部使用apple組件。
Vue.component你可以創(chuàng)建 受楼,也可以取組件垦搬。
vue的優(yōu)點(diǎn)是什么
低耦合。視圖(View)可以獨(dú)立于Model變化和修改艳汽,一個(gè)ViewModel可以綁定到不同的"View"上猴贰,當(dāng)View變化的時(shí)候Model可以不變,當(dāng)Model變化的時(shí)候View也可以不變
可重用性河狐。你可以把一些視圖邏輯放在一個(gè)ViewModel里面米绕,讓很多view重用這段視圖邏輯
可測(cè)試。界面素來是比較難于測(cè)試的馋艺,而現(xiàn)在測(cè)試可以針對(duì)ViewModel來寫
vue項(xiàng)目中的性能優(yōu)化
代碼層面:
1 不要在模板里面寫過多表達(dá)式
2 循環(huán)調(diào)用子組件時(shí)添加key栅干,并且避免使用v-for的時(shí)候同時(shí)使用v-if
3 頻繁切換的使用v-show,不頻繁切換的使用v-if
4 盡量少用float捐祠,可以用flex
5 按需加載碱鳞,可以用require或者import()按需加載需要的組件
6 路由懶加載,圖片懶加載踱蛀,第三方插件按需引入
7 區(qū)分?computed?和?watch?的使用
8 通過?addEventListener添加的事件在組件銷毀時(shí)要用?removeEventListener?手動(dòng)移除這些事件的監(jiān)聽
9 SSR服務(wù)端渲染窿给,首屏加載速度快贵白,SEO效果好
Webpack 層面優(yōu)化:
1 對(duì)圖片進(jìn)行壓縮
2 使用?CommonsChunkPlugin?插件提取公共代碼
3 提取組件的 CSS
4 優(yōu)化?SourceMap
5 構(gòu)建結(jié)果輸出分析,利用?webpack-bundle-analyzer?可視化分析工具
Vue的SPA 如何優(yōu)化加載速度
減少入口文件體積
靜態(tài)資源本地緩存
開啟Gzip壓縮
使用SSR,nuxt.js
Vue與Angular以及React的區(qū)別崩泡?
Vue與AngularJS的區(qū)別
Angular采用TypeScript開發(fā), 而Vue可以使用javascript也可以使用TypeScript
AngularJS依賴對(duì)數(shù)據(jù)做臟檢查禁荒,所以Watcher越多越慢;Vue.js使用基于依賴追蹤的觀察并且使用異步隊(duì)列更新角撞,所有的數(shù)據(jù)都是獨(dú)立觸發(fā)的呛伴。
AngularJS社區(qū)完善, Vue的學(xué)習(xí)成本較小
Vue與React的區(qū)別
vue組件分為全局注冊(cè)和局部注冊(cè),在react中都是通過import相應(yīng)組件谒所,然后模版中引用热康;
props是可以動(dòng)態(tài)變化的,子組件也實(shí)時(shí)更新劣领,在react中官方建議props要像純函數(shù)那樣褐隆,輸入輸出一致對(duì)應(yīng),而且不太建議通過props來更改視圖剖踊;
子組件一般要顯示地調(diào)用props選項(xiàng)來聲明它期待獲得的數(shù)據(jù)。而在react中不必需衫贬,另兩者都有props校驗(yàn)機(jī)制德澈;
每個(gè)Vue實(shí)例都實(shí)現(xiàn)了事件接口,方便父子組件通信固惯,小型項(xiàng)目中不需要引入狀態(tài)管理機(jī)制梆造,而react必需自己實(shí)現(xiàn);
使用插槽分發(fā)內(nèi)容葬毫,使得可以混合父組件的內(nèi)容與子組件自己的模板镇辉;
多了指令系統(tǒng),讓模版可以實(shí)現(xiàn)更豐富的功能贴捡,而React只能使用JSX語法忽肛;
Vue增加的語法糖computed和watch,而在React中需要自己寫一套邏輯來實(shí)現(xiàn)烂斋;
react的思路是all in js屹逛,通過js來生成html,所以設(shè)計(jì)了jsx汛骂,還有通過js來操作css罕模,社區(qū)的styled-component、jss等帘瞭;而 vue是把html淑掌,css,js組合到一起蝶念,用各自的處理方式抛腕,vue有單文件組件芋绸,可以把html、css兽埃、js寫到一個(gè)文件中侥钳,html提供了模板引擎來處理。
react做的事情很少柄错,很多都交給社區(qū)去做舷夺,vue很多東西都是內(nèi)置的,寫起來確實(shí)方便一些售貌, 比如 redux的combineReducer就對(duì)應(yīng)vuex的modules给猾, 比如reselect就對(duì)應(yīng)vuex的getter和vue組件的computed, vuex的mutation是直接改變的原始數(shù)據(jù)颂跨,而redux的reducer是返回一個(gè)全新的state敢伸,所以redux結(jié)合immutable來優(yōu)化性能,vue不需要恒削。
react是整體的思路的就是函數(shù)式池颈,所以推崇純組件,數(shù)據(jù)不可變钓丰,單向數(shù)據(jù)流躯砰,當(dāng)然需要雙向的地方也可以做到,比如結(jié)合redux-form携丁,組件的橫向拆分一般是通過高階組件琢歇。而vue是數(shù)據(jù)可變的,雙向綁定梦鉴,聲明式的寫法李茫,vue組件的橫向拆分很多情況下用mixin
vuex是什么?怎么使用肥橙?哪種功能場景使用它魄宏?
vuex 就是一個(gè)倉庫,倉庫里放了很多對(duì)象快骗。其中 state 就是數(shù)據(jù)源存放地娜庇,對(duì)應(yīng)于一般 vue 對(duì)象里面的 data
state 里面存放的數(shù)據(jù)是響應(yīng)式的,vue 組件從 store 讀取數(shù)據(jù)方篮,若是 store 中的數(shù)據(jù)發(fā)生改變名秀,依賴這相數(shù)據(jù)的組件也會(huì)發(fā)生更新
它通過 mapState 把全局的 state 和 getters 映射到當(dāng)前組件的 computed 計(jì)算屬性。
Vuex有5種屬性: 分別是 state藕溅、getter匕得、mutation、action、module;