概要
這篇文章首先梳理一下傳統(tǒng)MV的設(shè)計(jì)模式,然后以一個(gè)例子來(lái)說(shuō)明vue中的MVVM的思想。主要講什么是MV以及vue中的MVVM是什么樣子的,暫時(shí)不講實(shí)現(xiàn)原理。
傳統(tǒng)的意大利面條
<button style="....." onClick="if(....){....}else{.....}">...</button>
So, 為了避免意大利面條,一些框架創(chuàng)建了關(guān)注點(diǎn)分離
概念
M: 模型 => 數(shù)據(jù),業(yè)務(wù)邏輯,驗(yàn)證邏輯,模型常常包含業(yè)務(wù)邏輯。
V: 視圖 => 交互界面,是模型數(shù)據(jù)的可視化呈現(xiàn),視圖可能包含展示邏輯。
*: 這個(gè)部分將幫助管理模型與視圖間的關(guān)系,以及模型,視圖,用戶(hù)的關(guān)系。
傳統(tǒng)的設(shè)計(jì)模式
MVC
C: 控制器 => 接收來(lái)自UI控件的信號(hào),包含了處理用戶(hù)輸入的邏輯,基于接收到的輸入,發(fā)送命令給M,來(lái)更新V。在MVC中,V能夠捕獲M的變化,并且在觀察到模型變化的時(shí)候,更新視圖。

MVP
P: 視圖將職責(zé)委托給P,視圖僅僅用于相應(yīng)用戶(hù)的交互。P直接訪問(wèn)模型來(lái)獲取任何更新,將數(shù)據(jù)更新回傳給視圖。在這種模式下,P在模型和視圖之間扮演了中間人的角色。

V和M不發(fā)生聯(lián)系,都是通過(guò)P來(lái)傳遞。V不部署任何業(yè)務(wù)邏輯。而P非常厚,所有的業(yè)務(wù)邏輯都在這里
MVVM
VM: VM仍然是視圖與模型的中間人。包含了Property及其展示邏輯。在模型中,每一個(gè)需要在視圖里得以反應(yīng)的數(shù)據(jù)點(diǎn),都映射到了視圖模型的對(duì)應(yīng)Property上,VM能夠掌握視圖與模型的變化,并保持兩者同步。

MVVM和MVP唯一的不同就是采用了數(shù)據(jù)雙向綁定。V的變動(dòng)直接反映在了VM上,M的變化也直接反映在了VM上。
其實(shí)不用太在意前端框架是用的是哪種模式,沒(méi)有哪個(gè)框架是絕對(duì)去匹配一種模式,只有使用更適合的模式來(lái)實(shí)現(xiàn)前端框架。So,讓我們MVW(W: whatever)
vue的設(shè)計(jì)模式
現(xiàn)在用一個(gè)例子來(lái)說(shuō)明mvvm。我們要實(shí)現(xiàn)一個(gè)下面功能的mockup:

功能:
- 這個(gè)demo用來(lái)輸入一些用戶(hù)信息
- 界面的左邊輸入用戶(hù)信息
- 界面的右邊用來(lái)展示信息條目
- 點(diǎn)擊左邊的add按鈕將左邊的用戶(hù)信息添加到右邊的條目
- 右邊每個(gè)條目都有一個(gè)Delete按鈕,點(diǎn)擊按鈕刪除條目
下面就進(jìn)行分析:
模型(M)
每個(gè)模型都是現(xiàn)實(shí)世界中的一個(gè)事物,這里我們的模型包含三個(gè)字段:
name, number,email。我們的模型應(yīng)該是這樣的:
[
{
name: 'Haha',
number: '182****1234',
email: 'haha***@qq.com'
},
{
name: 'Hehe',
number: '182****1234',
email: 'hehe***@qq.com'
}
]
可以看出,模型是一個(gè)數(shù)組組成的列表,模型的數(shù)據(jù)來(lái)自用戶(hù)自己填寫(xiě)的表單,可視化效果就是mockup右側(cè)的樣子。有一些框架可以隱式的創(chuàng)建模型,就是不用顯示的聲明模型,而vue是顯示的聲明模型。
new Vue({
data(){
return {
userinfo: {
name: '',
number: '',
email: ''
},
users: []
}
}
})
使用框架的好處之一就是,除了應(yīng)用邏輯外,數(shù)據(jù)與UI綁定結(jié)合的邏輯將由框架處理。
視圖(V)
1.綁定
顧名思義就是將UI元素與相關(guān)代碼聯(lián)系起來(lái)。綁定的語(yǔ)法有兩種,一種是表達(dá)式,一種是命令。vue中有雙向綁定,單向綁定,單次綁定。
雙向綁定
在創(chuàng)建之后,改變?nèi)魏我欢耍硪欢藭?huì)跟著改變(模型和視圖同步)。主要體現(xiàn)在表單元素上。下面我們就將input控件的值綁定到userinfo的視圖模型上
<input v-model="userinfo.name" placeholder="name" />
單向綁定
顧名思義,一端的改變會(huì)影響另一端,反之則不影響。這種類(lèi)型的綁定用于不需要用戶(hù)輸入的元素。
<ul>
<li v-for="item in users">{{item.name}}<li>
</ul>
單次綁定
只綁定一次,后面數(shù)據(jù)在改變,視圖也不會(huì)更新。在vue中使用v-once渲染過(guò)一次之后,元素/組件及其所有的子節(jié)點(diǎn)將被視為靜態(tài)內(nèi)容并跳過(guò)。舉例:
<!-- 當(dāng)title再次改變時(shí)插值處的內(nèi)容將不會(huì)改變 -->
<h4 v-once>{{title}}</h4>
2.模板
vue中模板就是視圖。模板看似是一些html代碼。實(shí)則vue將它作為字符串,進(jìn)行了處理,讓看似html代碼中的插值和指令達(dá)到我們想要的效果。
模板渲染
這里簡(jiǎn)單的說(shuō)一下vue的模板渲染,我們將模板字符串給 template屬性,vue拿到這一段字符串會(huì)做一大堆工作,這里大概說(shuō)一下,后面分析源碼時(shí)會(huì)詳細(xì)分析。template先轉(zhuǎn)為AST,AST再轉(zhuǎn)成 render函數(shù),生成真是的dom。好講完了。
關(guān)注點(diǎn)分離
基于底層的設(shè)計(jì)模式,模型專(zhuān)注數(shù)據(jù),視圖專(zhuān)注數(shù)據(jù)展示,vm則是將模型和數(shù)據(jù)解耦,并維持兩者間的互相通信。記住一個(gè)原則,越是聚焦于單一目的,編碼,測(cè)試,更改就會(huì)越容易。
好了我感覺(jué)我已經(jīng)把vue的mvvm講述清楚了。先知道什么是vue的mvvm,然后再去搞懂vue是怎么實(shí)現(xiàn)的。哈哈哈