gitee
M:Model 数据模型(模型层)→ 操作数据库(对数据进行增删改查) V:View视图层 → 显示视图或视图模板 C:Controller 控制器层 → 逻辑层 数据和视图关联挂载和基本的逻辑操作 API层 前端请求的API对应的是控制器中的方法
服务端渲染
View需要数据 → Controller对应的方法 → 调用Model的方法 → 获取数据 → 返回给Controller对应的方法 → render到View中
前端渲染
前端 → 异步请求URL → 对应Controller中某个方法 → Model层的方法 → 操作数据库 → 获取数据 → 返回给Controller → 响应回前端
前端MVC
Model → 管理视图所需要的数据 → 数据与视图关联 View → HTML模板 + 视图渲染 Controller → 管理事件逻辑
Model : ① data → n1 n2 method res // 组织数据 ② watch → data change → update view // 数据监听/数据代理 变化时触发View.render() View : template → render // 组织+渲染/更新HTML模板 Controller : event trigger → model/data // 事件处理函数定义与绑定
(function () {
function init() {
model.init()
view.render()
controller.init()
}
var model = {
data: {
a: 0,
b: 0,
s: '+',
r: 0,
},
init: function () {
var _this = this;
for (var k in _this.data) {
(function (k) {
console.log('k', k)
Object.defineProperty(_this, k, {
get: function () {
console.log('get model')
return _this.data[k]
},
set: function (newVal) {
_this.data[k] = newVal
view.render({ [k]: newVal })
console.log('set model')
}
})
})(k)
}
}
}
var view = {
el: '#app',
template: `
<P>
<span class="cal-a">{{ a }}</span>
<span class="cal-s">{{ s }}</span>
<span class="cal-b">{{ b }}</span>
<span>=</span>
<span class="cal-r">{{ r }}</span>
</P>
<p>
<input type="text" placeholder="Number a" class="cal-input a"/>
<input type="text" placeholder="Number b" class="cal-input b"/>
</p>
<p>
<button class="cal-btn">+</button>
<button class="cal-btn">-</button>
<button class="cal-btn">*</button>
<button class="cal-btn">/</button>
</p>
`,
render: function (mutedData) {
if (!mutedData) {
this.template = this.template.replace(
/\{\{(.*?)\}\}/g,
function (node, key) {
return model[key.trim()]
}
)
var container = document.createElement('div')
container.innerHTML = this.template;
document.querySelector(this.el).appendChild(container)
} else {
for (var k in mutedData) {
document.querySelector('.cal-' + k).textContent = mutedData[k]
}
}
}
}
var controller = {
init: function () {
var oCalInputs = document.querySelectorAll('.cal-input'),
oCalBtns = document.querySelectorAll('.cal-btn'),
inputItem,
btnItem;
for (var i = 0; i < oCalInputs.length; i++) {
inputItem = oCalInputs[i];
inputItem.addEventListener('input', this.handleInput, false)
}
console.log(oCalBtns)
for (var i = 0; i < oCalBtns.length; i++) {
btnItem = oCalBtns[i];
btnItem.addEventListener('click', this.handleBtnClick, false)
}
},
handleInput: function (e) {
var tar = e.target,
value = Number(tar.value),
field = tar.className.split(' ')[1];
model[field] = value;
with (model) {
r = eval('a' + s + 'b')
}
},
handleBtnClick: function (e) {
var tar = e.target,
type = tar.textContent;
console.log('type', type)
model.s = type;
with (model) {
r = eval('a' + s + 'b')
}
}
}
init()
})()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MVC</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src='./index.js'></script>
</body>
</html>
|