概要
這篇文章首先梳理一下傳統MV的設計模式,然后以一個例子來說明vue中的MVVM的思想。主要講什么是MV以及vue中的MVVM是什么樣子的,暫時不講實現原理。
傳統的意大利面條
<button style="....." onClick="if(....){....}else{.....}">...</button>
So, 為了避免意大利面條,一些框架創建了關注點分離
概念
M: 模型 => 數據,業務邏輯,驗證邏輯,模型常常包含業務邏輯。
V: 視圖 => 交互界面,是模型數據的可視化呈現,視圖可能包含展示邏輯。
*: 這個部分將幫助管理模型與視圖間的關系,以及模型,視圖,用戶的關系。
傳統的設計模式
MVC
C: 控制器 => 接收來自UI控件的信號,包含了處理用戶輸入的邏輯,基于接收到的輸入,發送命令給M,來更新V。在MVC中,V能夠捕獲M的變化,并且在觀察到模型變化的時候,更新視圖。
MVP
P: 視圖將職責委托給P,視圖僅僅用于相應用戶的交互。P直接訪問模型來獲取任何更新,將數據更新回傳給視圖。在這種模式下,P在模型和視圖之間扮演了中間人的角色。
V和M不發生聯系,都是通過P來傳遞。V不部署任何業務邏輯。而P非常厚,所有的業務邏輯都在這里
MVVM
VM: VM仍然是視圖與模型的中間人。包含了Property及其展示邏輯。在模型中,每一個需要在視圖里得以反應的數據點,都映射到了視圖模型的對應Property上,VM能夠掌握視圖與模型的變化,并保持兩者同步。
MVVM和MVP唯一的不同就是采用了數據雙向綁定。V的變動直接反映在了VM上,M的變化也直接反映在了VM上。
其實不用太在意前端框架是用的是哪種模式,沒有哪個框架是絕對去匹配一種模式,只有使用更適合的模式來實現前端框架。So,讓我們MVW(W: whatever)
vue的設計模式
現在用一個例子來說明mvvm。我們要實現一個下面功能的mockup:
功能:
- 這個demo用來輸入一些用戶信息
- 界面的左邊輸入用戶信息
- 界面的右邊用來展示信息條目
- 點擊左邊的add按鈕將左邊的用戶信息添加到右邊的條目
- 右邊每個條目都有一個Delete按鈕,點擊按鈕刪除條目
下面就進行分析:
模型(M)
每個模型都是現實世界中的一個事物,這里我們的模型包含三個字段:
name, number,email。我們的模型應該是這樣的:
[
{
name: 'Haha',
number: '182****1234',
email: 'haha***@qq.com'
},
{
name: 'Hehe',
number: '182****1234',
email: 'hehe***@qq.com'
}
]
可以看出,模型是一個數組組成的列表,模型的數據來自用戶自己填寫的表單,可視化效果就是mockup右側的樣子。有一些框架可以隱式的創建模型,就是不用顯示的聲明模型,而vue是顯示的聲明模型。
new Vue({
data(){
return {
userinfo: {
name: '',
number: '',
email: ''
},
users: []
}
}
})
使用框架的好處之一就是,除了應用邏輯外,數據與UI綁定結合的邏輯將由框架處理。
視圖(V)
1.綁定
顧名思義就是將UI元素與相關代碼聯系起來。綁定的語法有兩種,一種是表達式,一種是命令。vue中有雙向綁定,單向綁定,單次綁定。
雙向綁定
在創建之后,改變任何一端,另一端會跟著改變(模型和視圖同步)。主要體現在表單元素上。下面我們就將input控件的值綁定到userinfo的視圖模型上
<input v-model="userinfo.name" placeholder="name" />
單向綁定
顧名思義,一端的改變會影響另一端,反之則不影響。這種類型的綁定用于不需要用戶輸入的元素。
<ul>
<li v-for="item in users">{{item.name}}<li>
</ul>
單次綁定
只綁定一次,后面數據在改變,視圖也不會更新。在vue中使用v-once
渲染過一次之后,元素/組件及其所有的子節點將被視為靜態內容并跳過。舉例:
<!-- 當title再次改變時插值處的內容將不會改變 -->
<h4 v-once>{{title}}</h4>
2.模板
vue中模板就是視圖。模板看似是一些html代碼。實則vue將它作為字符串,進行了處理,讓看似html代碼中的插值和指令達到我們想要的效果。
模板渲染
這里簡單的說一下vue的模板渲染,我們將模板字符串給 template屬性,vue拿到這一段字符串會做一大堆工作,這里大概說一下,后面分析源碼時會詳細分析。template先轉為AST,AST再轉成 render函數,生成真是的dom。好講完了。
關注點分離
基于底層的設計模式,模型專注數據,視圖專注數據展示,vm則是將模型和數據解耦,并維持兩者間的互相通信。記住一個原則,越是聚焦于單一目的,編碼,測試,更改就會越容易。
好了我感覺我已經把vue的mvvm講述清楚了。先知道什么是vue的mvvm,然后再去搞懂vue是怎么實現的。哈哈哈