MVVM 是 Model-View-ViewModel 的縮寫。html
Model
表明數據模型,也能夠在Model中定義數據修改和操做的業務邏輯。View
表明UI 組件,它負責將數據模型轉化成UI 展示出來。ViewModel
監聽模型數據的改變和控制視圖行爲、處理用戶交互,簡單理解就是一個同步View 和 Model的對象,鏈接Model和View。在MVVM架構下,View 和 Model 之間並無直接的聯繫,而是經過ViewModel進行交互,Model 和 ViewModel 之間的交互是雙向的, 所以View 數據的變化會同步到Model中,而Model 數據的變化也會當即反應到View 上。前端
ViewModel 經過雙向數據綁定把 View 層和 Model 層鏈接了起來,而View 和 Model 之間的同步工做徹底是自動的,無需人爲干涉,所以開發者只需關注業務邏輯,不須要手動操做DOM, 不須要關注數據狀態的同步問題,複雜的數據狀態維護徹底由 MVVM 來統一管理。vue
注意, MVVM模型中, Model和View是不會直接鏈接的,而ViewModel則會以雙向鏈接的形式鏈接Model和View。面試
節選自 Vue的官方文檔,筆者我進行了一些梳理,想了解得具體些的話仍是猛戳連接吧。
二者具備許多的類似之處segmentfault
Vue與React的不一樣之處後端
shouldComponentUpdate
來避免沒必要要的子組件的重渲染,而Vue中組件的依賴是在渲染過程當中自動追蹤的,因此係統能精確知曉哪一個組件確實須要被重渲染。組件做用域的CSS 在React中,CSS 做用域是經過 CSS-in-JS 的方案實現的 (好比 styled-components、glamorous 和 emotion),而Vue則有更好的解決方案,以下:瀏覽器
<style scoped> @media (min-width: 250px) { .list-container:hover { background: orange; } } </style>
這個可選 scoped
屬性會自動添加一個惟一的屬性 (好比 data-v-21e5b78
) 爲組件內 CSS 指定做用域,編譯的時候 .list-container:hover
會被編譯成相似 .list-container[data-v-21e5b78]:hover
,這樣就能夠控制CSS只在這個組件內生效。緩存
具體能夠參照官網的這張圖,左側以紅色框表示的都是階段安全
大體過程就是網絡
vue實現數據雙向綁定主要是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來做爲它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉爲 getter/setter。用戶看不到 getter/setter,可是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
vue的數據雙向綁定 將MVVM做爲數據綁定的入口,整合Observer,Compile和Watcher三者,經過Observer來監聽本身的model的數據變化,經過Compile來解析編譯模板指令,最終利用watcher搭起observer和Compile之間的通訊橋樑,達到數據變化 —>視圖更新;視圖交互變化(input)—>數據model變動雙向綁定效果。
路由的實現有兩種:hash和history interface來實現前端路由,
hash在瀏覽器中符號「#」,#以及#後面的字符稱之爲hash,用window.location.hash讀取;特色:
(1)hash雖然在URL中,但不被包括在HTTP請求中
(2)用來指導瀏覽器動做,對服務端安全無用,hash不會重加載頁面
history採用h5的新特性;且提供了兩個新方法:pushState(),replaceState()能夠對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變動,不過history有個問題是:若是用戶直接在地址欄中輸入並回車,瀏覽器重啓或從新加載時,history模式會將url修改的和正常請求後端同樣,此狀況下,從新向後端發送請求,後端若是沒有配置對應路由處理,則返回404,解決方法是後端配置一下。
<router-link :to="{path:'/index',params:{id:num}}"> <router-link :to="{ path:'/index' , query:{id:num}}">
而後經過$route.params來讀取數據,但路由傳遞參數值是對象的話就不行了會報錯,傳遞前用base64轉譯一下就能夠了。
父組件經過標籤上面定義傳值
<parent> <child :child-msg="msg"></child> //這裏必需要用 - 代替駝峯 </parent> data(){ return { msg: [1,2,3] }; }
子組件經過props
方法接受數據
子組件經過props來接收數據: 方式1: props: ['childMsg'] 方式2 : props: { childMsg: Array //這樣能夠指定傳入的類型,若是類型不對,會警告 } 方式3: props: { childMsg: { type: Array, //傳入的類型 default: [0,0,0] //這樣能夠指定默認的值 } }
子組件經過$emit
方法傳遞參數
<template> <div @click="testClick"></div> </template> methods: { testClick() { this.$emit('test','123'); //$emit(even,value)even 是一個函數,value 是傳給父組件的值 , 觸發名爲test方法, '123'爲向父組件傳遞的數據 } }
父組件經過v-on
(簡寫爲@
)來監聽DOM事件,並在觸發時接收數據運行js函數。
<div> <child @test="change" :msg="msg"></child> //監聽子組件觸發的test事件,而後調用change方法 </div> methods: { change(val) { this.msg = val; // val: 123 } }
若是2個組件不是父子組件那麼如何通訊呢?這時能夠經過eventHub
來實現通訊.
所謂eventHub
就是建立一個事件中心,至關於中轉站,能夠用它來傳遞事件和接收事件.
let Hub = new Vue(); //建立事件中心
組件1觸發:
<div @click="eve"></div> methods: { eve() { Hub.$emit('change','hehe'); //Hub觸發事件 } }
組件2接收:
<div></div> created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }
Vue的條件渲染涉及到兩個不一樣的關鍵字 v-if
和 v-show
v-if
v-if
是真正的條件渲染,它會適當地銷燬和重建DOM達到讓元素顯示和隱藏的效果。
(Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染,能夠看一下第二段程序)v-if
也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div>
Vue 爲你提供了一種方式來表達「這兩個元素是徹底獨立的,不要複用它們」。
只需添加一個具備惟一值的 key
屬性便可,沒有 key
說明的話就會被複用:
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
注意,<label>
元素仍然會被高效地複用,由於它們沒有添加 key
屬性。
v-show
經過修改元素的display的CSS屬性讓其顯示或者隱藏,元素始終會被渲染並保留在DOM中。
<h1 v-show="ok">Hello!</h1> //ok 在data裏進行賦值爲true或者false
v-if
vs v-show
通常來講,v-if
有更高的切換開銷,而 v-show
有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show
較好;若是在運行時條件不多改變,則使用 v-if
較好。
歡迎諸位同道們留言補充ヾ(◍°∇°◍)ノ゙
參考連接
Vue官方教程
MVVM - 廖雪峯的官方網站
MVC,MVP 和 MVVM 的圖示 - 阮一峯的網絡日誌
vue.js學習筆記(一):什麼是mvvm框架,vue.js的核心思想 - _林沖 - 博客園
vue父子組件通訊 - Hi-Sen - 博客園
Vue 成長之路(一) - 媛媛碼農成長記 - SegmentFault 思否