mvvm 雙向綁定,採用數據劫持結合發佈者-訂閱者模式的方式,經過 Object.defineProperty()
來劫持各個屬性的 setter、getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。
css
幾個要點: 一、實現一個數據監聽器 Observer,可以對數據對象的全部屬性進行監聽,若有變更可拿到最新值並通知訂閱者 二、實現一個指令解析器 Compile,對每一個元素節點的指令進行掃描和解析,根據指令模板替換數據,以及綁定相應的更新函數 三、實現一個 Watcher,做爲鏈接 Observer 和 Compile 的橋樑,可以訂閱並收到每一個屬性變更的通知,執行指令綁定的相應回調函數,從而更新視圖 四、mvvm 入口函數,整合以上三者html
具體步驟:前端
當 Vue 進入初始化階段時,一方面 Vue 會遍歷 data 中的屬性,並用 Object.defineProperty 將它轉化成 getter/setter 的形式,實現數據劫持(暫不談 Vue3.0 的 Proxy);另外一方面,Vue 的指令編譯器 Compiler 對元素節點的各個指令進行解析,初始化視圖,並訂閱 Watcher 來更新試圖,此時 Watcher 會將本身添加到消息訂閱器 Dep 中,此時初始化完畢。 當數據發生變化時,觸發 Observer 中 setter 方法,當即調用 Dep.notify(),Dep 這個數組開始遍歷全部的訂閱者,並調用其 update 方法,Vue 內部再經過 diff 算法,patch 相應的更新完成對訂閱者視圖的改變。vue
響應式系統簡述:node
詳細實現見 面試官: 你對虛擬DOM原理的理解?react
考點: Vue 的變化偵測原理 前置知識: 依賴收集、虛擬 DOM、響應式系統 現代前端框架有兩種方式偵測變化,一種是pull,一種是pushwebpack
pull: 其表明爲React,咱們能夠回憶一下React是如何偵測到變化的,咱們一般會用setStateAPI顯式更新,而後React會進行一層層的Virtual Dom Diff操做找出差別,而後Patch到DOM上,React從一開始就不知道究竟是哪發生了變化,只是知道「有變化了」,而後再進行比較暴力的Diff操做查找「哪發生變化了」,另一個表明就是Angular的髒檢查操做。nginx
push: Vue的響應式系統則是push的表明,當Vue程序初始化的時候就會對數據data進行依賴的收集,一但數據發生變化,響應式系統就會馬上得知。所以Vue是一開始就知道是「在哪發生變化了」,可是這又會產生一個問題,若是你熟悉Vue的響應式系統就知道,一般一個綁定一個數據就須要一個Watcher,一但咱們的綁定細粒度太高就會產生大量的Watcher,這會帶來內存以及依賴追蹤的開銷,而細粒度太低會沒法精準偵測變化,所以Vue的設計是選擇中等細粒度的方案,在組件級別進行push偵測的方式,也就是那套響應式系統,一般咱們會第一時間偵測到發生變化的組件,而後在組件內部進行Virtual Dom Diff獲取更加具體的差別,而Virtual Dom Diff則是pull操做,Vue是push+pull結合的方式進行變化偵測的。web
當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用「就地複用」策略。若是數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。key 的做用主要是爲了高效的更新虛擬DOM。
beforeCreate
和created
beforeMount
和mounted
beforeUpdate
和updated
beforeDestory
和destoryed
activated
和deactivated
使用Object.assign(),vm.$data能夠獲取當前狀態下的data,vm.$options.data(this)能夠獲取到組件初始化狀態下的data。
Object.assign(this.$data, this.$options.data(this)) // 注意加this,否則取不到data() { a: this.methodA } 中的this.methodA。
官方文檔:vue-router鉤子函數
router.beforeEach
router.beforeResolve
router.afterEach
beforeEnter
beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
route
和 router
的區別是什麼?route
是「路由信息對象」,包括path
,params
,hash
,query
,fullPath
,matched
,name
等路由信息參數。
router
是「路由實例對象」,包括了路由的跳轉方法(push
、replace
),鉤子函數等。
1.監聽數據變化的實現原理不一樣
Vue 不須要特別的優化就能達到很好的性能,而對於 React 而言,須要經過 PureComponent/shouldComponentUpdate 這個生命週期方法來進行控制。若是你的應用中,交互複雜,須要處理大量的 UI 變化,那麼使用 Virtual DOM 是一個好主意。若是你更新元素並不頻繁,那麼 Virtual DOM 並不必定適用,性能極可能還不如直接操控 DOM。
爲何 React 不精確監聽數據變化呢?這是由於 Vue 和 React 設計理念上的區別,Vue 使用的是可變數據,而 React 更強調數據的不可變。
2.數據流的不一樣
不過因爲咱們通常都會用 Vuex 以及 Redux 等單向數據流的狀態管理框架,所以不少時候咱們感覺不到這一點的區別了。
3.模板渲染方式的不一樣
在表層上,模板的語法不一樣
在深層上,模板的原理不一樣,這纔是他們的本質區別:
對這一點,我我的比較喜歡 React 的作法,由於他更加純粹更加原生,而 Vue 的作法顯得有些獨特,會把 HTML 弄得很亂。舉個例子,說明 React 的好處:react 中 render 函數是支持閉包特性的,因此咱們 import 的組件在 render 中能夠直接調用。可是在 Vue 中,因爲模板中使用的數據都必須掛在 this 上進行一次中轉,因此咱們 import 一個組件完了以後,還須要在 components 中再聲明下,這樣顯然是很奇怪但又不得不這樣的作法。
1. 爲何須要 nextTick Vue 是異步修改 DOM 的而且不鼓勵開發者直接接觸 DOM,但有時候業務須要必須對數據更改--刷新後的 DOM 作相應的處理,這時候就可使用 Vue.nextTick(callback)這個 api 了。
2. 理解原理前的準備 首先須要知道事件循環中宏任務和微任務這兩個概念(這其實也是面試常考點)。請閱大佬文章--完全搞懂瀏覽器 Event-loop 常見的宏任務有 script, setTimeout, setInterval, setImmediate, I/O, UI rendering 常見的微任務有 process.nextTick(Nodejs),Promise.then(), MutationObserver;
3. 理解 nextTick 而 nextTick 的原理正是 vue 經過異步隊列控制 DOM 更新和 nextTick 回調函數前後執行的方式。若是你們看過這部分的源碼,會發現其中作了不少 isNative()的判斷,由於這裏還存在兼容性優雅降級的問題。可見 Vue 開發團隊的深思熟慮,對性能的良苦用心。 若是你比較瞭解了前面的事件循環原理,推薦你看看這篇文章 請閱大佬文章--全面解析 Vue.nextTick 實現原理
有五種,分別是 State
、Getter
、Mutation
、Action
、Module
而後找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加如下代碼
externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'element-ui': 'ELEMENT', },
這樣 webpack 就不會把 vue.js, vue-router, element-ui 庫打包了。聲明一下,我把 main.js 中對 element 的引入刪掉了,否則我發現打包後的 app.css 仍是會把 element 的 css 打包進去,刪掉後就沒了。
而後你打包就會發現 vendor 文件小了不少~
import
或者require
懶加載。你打包就會發現,多了不少 1.xxxxx.js;2.xxxxx.js 等等,而 vendor.xxx.js 沒了,剩下 app.js 和 manifest.js,並且 app.js 還很小,我這裏是 100k 多一點。
找到 config/index.js,修改成 productionSourceMap: false
這個優化是兩方面的,前端將文件打包成.gz文件,而後經過nginx的配置,讓瀏覽器直接解析.gz文件。
若是首頁真的有瓶頸,能夠考慮用 node 單獨作服務端渲染,而下面的子頁面仍用 spa 單頁的方式交互。 這裏不推薦直接用 nuxt.js 服務端渲染方案,由於這樣一來增長了學習成本,二來服務端的維護成本也會上升,有時在本機測試沒問題,在服務端跑就有問題,爲了省心,仍是最大限度的使用靜態頁面較好。
參考連接: vue首屏加載優化 vue項目首屏加載優化實戰
關於Vue 3.0有幸看過尤大的關於3.0版本的RFC Vue Function-based API RFC。大體說了三個點,第一個是關於提出的新API setup()
函數,第二個說了對於Typescript的支持,最後說了關於替換Object.defineProperty
爲 Proxy 的支持。
詳細說了下關於Proxy代替帶來的性能上的提高,由於傳統的原型鏈攔截的方法,沒法檢測對象及數組的一些更新操做,但使用Proxy又帶來了瀏覽器兼容問題。
首先須要知道 vue-cli 是什麼?它是基於 Vue.js 進行快速開發的完整系統,也能夠理解成是不少 npm 包的集合。其次,vue-cli 完成的功能有哪些?
.vue 文件 --> .js 文件 ES6 語法 --> ES5 語法 Sass,Less,Stylus --> CSS 對 jpg,png,font 等靜態資源的處理 熱更新 定義環境變量,區分 dev 和 production 模式 ...
若是開發者須要補充或修改默認設置,須要在 package.json 同級下新建一個 vue.config.js 文件
更多vue面試題: 面試必備的13道能夠觸類旁通的Vue面試題 vue 248個知識點(面試題)爲你保駕護航 <br> 2019前端面試系列——CSS面試題 2019前端面試系列——JS面試題 2019前端面試系列——JS高頻手寫代碼題 2019前端面試系列——Vue面試題 2019前端面試系列——HTTP、瀏覽器面試題
原文出處:https://www.cnblogs.com/chenwenhao/p/11258895.html