MVC是什么事镣?
MVC是一種編程思路,或者說是一種程序架構(gòu)
注意:它不是框架
MVC將程序結(jié)構(gòu)分為三層:View(視圖層)揪胃、Model(數(shù)據(jù)層)璃哟、Controller(控制層)。
- View層:用戶展示信息喊递,只與Controller通信
- Model層:主要用于處理數(shù)據(jù)随闪,只與Controller通信
- Controller層:作為中間人,從View層接收信息骚勘,告訴Model層铐伴,Model層進行數(shù)據(jù)更新后撮奏,通知Controller,Controller再進行處理后告知View進行展示当宴。
這三個層每個都是一個獨立的部分畜吊,它們之間的交互要遵循一定的規(guī)則:View不能與Model直接聯(lián)系,必須通過Controller進行交互户矢。
如:
上圖展示的是一個MVC模型之間的數(shù)據(jù)流向玲献,可以看到View和Model是通過Controller來進行交互的
再以用戶上網(wǎng)為例進行說明,如下圖:
以用戶搜索“美食為例”梯浪,當(dāng)用戶按下Enter鍵發(fā)送請求捌年,該請求到了服務(wù)器(Controller),服務(wù)器本身并不存儲數(shù)據(jù)驱证,它會通知數(shù)據(jù)庫(Model)去找美食延窜,數(shù)據(jù)庫找到之后,將數(shù)據(jù)返回給服務(wù)器(Controller)抹锄,服務(wù)器對數(shù)據(jù)進行處理,然后生成頁面(View)顯示給用戶看荠藤,這便是一個MVC架構(gòu)的網(wǎng)址的執(zhí)行流程
針對于前端代碼的MVC
前端代碼中的MVC伙单,簡單描述就是:Controller監(jiān)聽View層(一般是DOM節(jié)點)的變化,然后通過Model層(數(shù)據(jù)層)哈肖,數(shù)據(jù)層進行數(shù)據(jù)的處理吻育,處理完成后通知Controller層,Controller再通知View層進行渲染
面試問題:
- MVC是什么淤井?
- MVVM是什么布疼?
- React與Vue分別是什么?有什么區(qū)別币狠?
參考:《基于MVC的Javascript的富應(yīng)用》
注意:在前端領(lǐng)域看源代碼不是個很好的學(xué)習(xí)方式游两,一是因為更新?lián)Q代太快,二是大部分寫的一般漩绵,最重要的是要理解它背后的邏輯贱案,了解其原理
可以看下:preact這個庫,是react的精簡版止吐,只有4k代碼
MVC
- M:數(shù)據(jù)宝踪,只與數(shù)據(jù)有關(guān)
- V:視圖
- C:控制操作,調(diào)用Model碍扔,渲染View
MVC就是將代碼分成3個層次瘩燥,
- Model只與數(shù)據(jù)有關(guān),其他均不管不同;它是最地下的一層厉膀,是核心數(shù)據(jù)層
- View只與HTML有關(guān),其他均不管,它是在最上面的一層站蝠,面向用戶
- 而Controller汰具,是控制著Model和View,相當(dāng)于作為一個中間人的地址菱魔,當(dāng)Model數(shù)據(jù)更新了就調(diào)用View進行渲染留荔,當(dāng)檢測到View中操作,就調(diào)用Model 進行數(shù)據(jù)更改澜倦,更改完成后聚蝶,再執(zhí)行View進行渲染;
Controller監(jiān)聽View層藻治,如果View有變動碘勉,則對Model進行更新,更新完成后再進行渲染桩卵;
Controller同時可以監(jiān)聽Model層验靡,當(dāng)Model層有變動,則對View層進行修改
Model和View之間是不會相互操作的
//-------- View 視圖層
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack-demos</title>
</head>
<body>
<div class="modules">
<div class="module1">
</div>
<div class="module2">
</div>
<div class="module3">
<input type="text" name="number2">
<button name="button2">點我</button>
</div>
</div>
<script id="module2Template" type="text/x-handlerbars">
<hr>
<div>{{number}}</div>
<hr>
<button name="increase">加</button>
<hr>
<button name="decrease">減</button>
</script>
<script type="text/javascript" src="bundle.js"></script></body>
</html>
// Controller 類
import $ from 'jquery'
const Handlebars = require('handlebars');
class Controller{
constructor(options){
for(let key in options){
this[key] = options[key]
}
this.$element = $(this.element)
this.init && this.init()
if(this.template && this.render){
this.render()
}
this.bindEvents()
}
bindEvents(){
for(let key in this.events){
let parts = key.split(' ')
let eventType = parts.shift()
let selector = parts.join(' ')
if(typeof this.events[key] === 'function'){
this.$element.on(eventType, selector, this.events[key])
}else if(typeof this.events[key] === 'string'){
let methodName = this.events[key]
this.$element.on(eventType, selector, this[methodName].bind(this))
}
}
}
render(){
let template = (this.template[0] === '#') ?
(document.querySelector(this.template).innerHTML) :
this.template
let html = Handlebars.compile(template)(this.model.data)
this.$element.html(html)
}
}
export default Controller
import Controller from './Controller'
import $ from 'jquery'
// ----------這是Model層
let model = {
data: {
number: 0
},
get(){
return $.get('/data.json').then((response)=>{
this.data = response
return this.data
})
},
increase(){ // 向服務(wù)器發(fā)請求
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('500ms 過去了')
this.data.number += 1
resolve(this.data)
},500)
})
},
decrease(){ // 向服務(wù)器發(fā)請求
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('500ms 過去了')
this.data.number -= 1
resolve(this.data)
},500)
})
}
}
// ------------這是Controller實例
new Controller({
element: '.module2',
template: '#module2Template',
model: model,
events: {
'click button[name=increase]': 'increase',
'click button[name=decrease]': 'decrease',
},
init(){
this.model.get().then(()=>{
this.render()
})
},
increase(){
this.model.increase().then(()=>{
this.render()
})
},
decrease(){
this.model.decrease().then(()=>{
this.render()
})
}
})