标签:dex 而且 异常 body sig control com mod ons
MVC的解释千千万,唯一统一的认识就是MCV分别指model、view、controller,至于其它的咱也不知道对错。
MVC是把业务按照M、V、C的功能进行解耦:
Model用来管理业务逻辑相关的数据以及对数据的处理方法
View=render(data)用来展示Model里数据的当下状态,并实时跟随Model更新
Controller负责接受并响应View上用户的交互行为以及对Model内部数据进行操作
刚学编程时,为了完成一个功能,我们想到什么写什么,只要最后能凑出来就成。这种代码常称为“意大利面条”代码,就是一坨*的意思,而且面条之间没有章法可循,你不知道它从哪来,也不知道它到哪去,一旦项目大起来,改代码的工作量比从头写的工作量还大,事情朝着不可控的方向发展了去,改代码的人就很惨。
于是,理清业务逻辑,形成代码规范,方便日后维护,就显得异常重要,so前端开始借鉴后端的架构设计模式,实现了各种MV*框架
(1)第一步
import ‘./app.css‘
import $ from ‘jquery‘
// 数据相关都放到m
const m = {
data: {
n: parseInt(localStorage.getItem(‘n‘))
}
}
// 视图相关都放到v
const v = {
el: null,
html: `
<div id="add">{{n}}</div>
<button id="btn">+1</button>
`,
render(n) {
$(v.html.replace(‘{{n}}‘, n))
.appendTo($(‘body>#app‘))
}
}
// 其他都放c
const c = {
init() {
c.ui = {
$number: $(‘add‘),
$btn: $(‘btn‘)
}
c.bindEvents()
},
bindEvents(){
c.ui.$btn.on(‘click‘, ()=>{
let n = m.data.n
n+=1
localStorage.setItem(‘n‘, n)
c.ui.$number.text(n)
})
}
}
v.render()
c.init()
(2)第二步
import "./app.css"
import $ from "jquery"
import Model from "./base/Model.js"
import View from "./base/View"
const m = new Model({
data: {
//初始化数据
n: parseFloat(localStorage.getItem(‘n‘)) || 100,
},
update: function(data){
Object.assign(m.data, data)
m.trigger(‘m:updated‘)
localStorage.setItem(‘n‘, m.data.n.toString())
}
})
const init = (el)=>{
new View({
el: el,
data: m.data,
// 初始化html
html: `
<div class="output">
<span id="number">{{n}}</span>
</div>
<div class="actions">
<button id="add">+1</button>
</div>`,
render(data){
if(this.el.children.length !== 0) this.el.empty()
$(this.html.replace(‘{{n}}‘, data.n)).appendTo(this.el)
},
events: {
‘click #add‘: ‘add‘,
},
add(){
m.update({n: m.data.n + 1})
},
})
}
export default init
表驱动编程就像封装函数,函数参数(包括)与存在映射关系的对象一一对应,来减少大量重复代码。
再拿上面的例子来说,加上减、乘、除的功能:
events: {
‘click #add‘: ‘add‘,
‘click #sub‘: ‘sub‘,
‘click #mul‘: ‘mul‘,
‘click #div‘: ‘div‘,
},
add(){
m.update({n: m.data.n + 1})
},
sub(){
m.update({n: m.data.n - 1})
},
mul(){
m.update({n: m.data.n * 2})
},
div(){
m.update({n: m.data.n / 2})
}
可以简化成
for(let item in this.events) {
const operate = this[this.events[item]]
const spaceIndex = item.indexOf(‘ ‘)
const eventName = item.slice(0, spaceIndex)
const element = item.slice(spaceIndex+1)
this.el.on(eventName, element, operate)
}
上面的例子可以看到,View既要从M中取数据,还会根据用户操作来改变M中的数据,这中间少不了两个层之间的交互,以及监听,这就要EventBus来镇场子了。如何监听data的改变的呢?
Model:m.trigger(‘m:updated‘)
View:m.update({n: m.data.n + 1})
当data改变时,会调用m.update()方法,此方法里的m.tigger(‘m:updated‘)会有一个专门的机制来监听它,就是下面的this.on,监听到m:updated就立即从新渲染页面那一块的数据。
this.on(‘m:updated‘, ()=>{
this.render(this.data)
})
在层层封装之下,底层都离不开EventBus的事件监听,因为数据是活的,会被传递。这里我们可以自己造一个事件,来满足不同条件下的监听需求。然后通过继承,让每个实例都有监听功能。
参考链接:https://efe.baidu.com/blog/mvc-deformation/
标签:dex 而且 异常 body sig control com mod ons
原文地址:https://www.cnblogs.com/fourther/p/13343076.html