网站建设金硕网络,公司注册网站多少钱,暴富建站,京东商城网站的搜索引擎营销做的案例分析MVC是什么#xff1f; MVC是一种架构模式#xff0c;它将应用抽象为3个部分#xff1a;模型#xff08;数据#xff09;、视图、控制器#xff08;分发器#xff09;。 本文将用一个经典的例子todoList来展开#xff08;代码在最后#xff09;。 一个事件发生的过程 MVC是一种架构模式它将应用抽象为3个部分模型数据、视图、控制器分发器。 本文将用一个经典的例子todoList来展开代码在最后。 一个事件发生的过程通信单向流动 1、用户在视图 V 上与应用程序交互 2、控制器 C 触发相应的事件要求模型 M 改变状态读写数据 3、模型 M 将数据发送到视图 V 更新数据展现给用户 在js的传统开发模式中大多基于事件驱动的 1、hash驱动 2、DOM事件用来驱动视图 3、模型事件业务模型事件和数据模型事件用来驱动模型和模型结合 所以js中的mvc的特点是单向流动、事件驱动 一模型 模型存放着应用的所有数据对象业务数据、数据校验、增删改查比如例子todoList中的store模型存放每一条记录及与之有关的逻辑。 数据是面向对象的当控制器请求模型读写数据时模型就将数据包装成模型实例。任何定义在这个数据模型上的函数或逻辑都可以直接被调用。在本文的例子中采用localSrorage也是类似道理的。存储的Todos可以随时被调用 模型不关心不包含视图和控制器的逻辑。它们应该是互相解耦的。这里提一点模型与视图的耦合显然是违反MVC架构原则但往往我们有时候却因为业务关系而无法完全解耦 模型表现了领域特定的数据当一个模型有所改变的时候它会通知它的观察者视图。 二视图 视图是呈现给用户的是用户交互的第一入口。它定义配置、管理着每个页面相应的模板与组件它表现为一个模型的当前状态视图通过观察者模式监视模型以获得最新的数据来呈现最新的页面。所以页面首次加载时往往是从接收模型的数据开始。 三控制器 控制器分发器是模型和视图之间的桥梁集中式地配置和管理事件分发、模型分发、视图分发还用来权限控制、异常处理等。我们的应用中往往是有多个控制器的 页面加载完成后控制器会监听视图的用户交互按钮点击或表单提交一旦用户发生交互时控制器做出对视图的选择触发控制器的事件处理机制去派发新的事件通知模型更新数据这样就回到了第一步了 Demo-todoList 最后这里是一个用原生js写的todoLIst这个demo做的很简陋点击输入文字点击确定就添加删除是直接点击该行信息。 单独分离开来举例子不好讲所以在代码中进行注释。首先简单理下下边代码的思路 1、V层定义配置了一个显示数据的字符串模板同时定义一个订阅者的回调函数render() 用于页面更新数据。 2、C层监听用户的添加与删除操作添加是add() 函数 它执行了回调函数render同时向M层写入数据通知M层改变。删除操作同理。 3、M层是本地存储localStorage模拟一个存储数据对象的后台模型。 1 !DOCTYPE html2 html langen3 head4 meta charsetUTF-85 titletodo/title6 /head7 body8 header9 h3待定事项/h310 /header11 main12 ul idtodoList/ul13 input typetext idcontent14 button idconfirm确认/button15 /main16 17 script18 (function () {19 const ADD_KEY __todoList__20 21 const Utils {22 // 模拟 Modal(实体模型)23 store(key, data) {24 if (arguments.length 1) {25 return localStorage.setItem(key, JSON.stringify(data));26 } else {27 let storeData localStorage.getItem(key);28 return (storeData JSON.parse(storeData)) || []; // 这里一定要设置初始值为 []29 }30 }31 }32 33 class Todo {34 constructor(id, text ) {35 this.id id36 this.text text37 }38 }39 40 let App {41 init() {42 // this.todos 为一个存储json对象的数组, 是一个实例化的数据对象,可任意调用43 this.todos Utils.store(ADD_KEY)44 this.findDom()45 this.bindEvent()46 this.render() // 初始化渲染47 },48 49 50 findDom() {51 this.contentBox document.querySelector(#content)52 this.confirm document.querySelector(#confirm)53 this.todoList document.querySelector(#todoList)54 this.todoListItem document.getElementsByTagName(li)55 },56 57 // 模拟 Controller (业务逻辑层)58 bindEvent() {59 this.confirm.addEventListener(click, () {60 // 要求模型 M 改变状态add()函数是写入数据操作61 this.add()62 }, false)63 64 this.todoList.addEventListener(click, (item) { // 事件委托优化性能65 this.remove(item)66 }, false)67 },68 69 // 这里勉强抽象成一个视图吧!!!70 view() {71 let fragment document.createDocumentFragment() // 减少回流次数72 fragment 73 74 for (let i 0; i this.todos.length; i) { // 一次性DOM节点生成75 // 这里使用拼接字符串代替视图的模板,76 // *******注意模板并不是一个视图,模板是由视图定义配置出来的,并被其管理着*******77 // 模板是用一种声明的方式指定部分甚至所有的视图对象78 fragment li${this.todos[i].text}/li79 }80 this.todoList.innerHTML fragment81 },82 83 // render()函数作为一个订阅者的回调函数数据的变化会反馈到模型 store84 // 换句话说视图通过观察者模式观察模型 store当模型发生改变触发视图更新85 render() {86 this.view()87 88 /**89 * 这里需要特别提一下,按照 MVC 原则这里本不应该出现下面的代码的90 * 因为业务逻辑关系我本地存储使用的是同一个key值再次写入数据会覆盖原来的数据91 * 所以必须通知模型 M 保存数据 V 层处理了不该它处理的逻辑导致 M 与 V 耦合92 *93 * 解决办法是将其抽象出来编写一个 视图助手 helper94 */95 Utils.store(ADD_KEY, this.todos)96 },97 98 getItemIndex(item) {99 let itemIndex
100 if (item.target.tagName.toLowerCase() li) {
101 let arr Array.prototype.slice.call(this.todoListItem)
102 let index arr.indexOf(item.target)
103 return itemIndex index
104 }
105 },
106
107 add(e) {
108 let id Number(new Date())
109 let text this.contentBox.value
110 let addTodo new Todo(id, text)
111 this.todos.unshift(addTodo) // 模型发生改变
112 this.render() // 当模型发生改变触发视图更新
113 },
114
115 remove(item) {
116 let index this.getItemIndex(item)
117 this.todos.splice(index, 1)
118 this.render()
119 }
120 }
121
122 App.init()
123 })()
124 /script
125 /body
126 /html 随着界面和逻辑的复杂用js或者jq去控制DOM是不现实的。上边例子只是用原生js模拟mvc的思想实现过程。真正地项目往往会依赖一些封装好的优秀库进行高效开发。 mvc模式的优点 mvc编程把所有精力放在数据处理尽可能减少对网页元素的处理。对于有一定数量功能的网页Mvc模式下强制规范代码简化减少重复代码使代码易于扩充。 mvc模式的弊端 1、清晰的构架以代码的复杂性为代价 对小项目反而降低开发效率。 如果本文的例子todoList用面条式代码编写那得多简单啊2、控制层和视图层耦合导致没有真正分离和重用 3、在同一业务逻辑下如果存在多种视图呈现需要视图定义配置多个模板引擎、数据解析多次处理数据与页面更新。代码就充满了各种选择器与事件回调随着业务的膨胀变得难以维护。 总结其实现在MVC在前端用得比较少了因为它的局限性催生了MVVM模式的流行与广泛使用在下篇文章我会谈谈我对MVVM的理解以及为何我使用基于MVVM模式的vue框架来高效开发。转载于:https://www.cnblogs.com/LIUYANZUO/p/7231703.html