<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        老生常談js中的MVC

        來源:懂視網 責編:小采 時間:2020-11-27 22:34:14
        文檔

        老生常談js中的MVC

        老生常談js中的MVC:MVC是什么? MVC是一種架構模式,它將應用抽象為3個部分:模型(數據)、視圖、控制器(分發器)。 本文將用一個經典的例子todoList來展開(代碼在最后)。 一個事件發生的過程(通信單向流動): 1、用戶在視圖 V 上與應用程序交互 2、控制器 C 觸發相
        推薦度:
        導讀老生常談js中的MVC:MVC是什么? MVC是一種架構模式,它將應用抽象為3個部分:模型(數據)、視圖、控制器(分發器)。 本文將用一個經典的例子todoList來展開(代碼在最后)。 一個事件發生的過程(通信單向流動): 1、用戶在視圖 V 上與應用程序交互 2、控制器 C 觸發相

        MVC是什么?

        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,模擬一個存儲數據對象的后臺模型。

        <!DOCTYPE html>
        <html lang="en">
        <head>
         <meta charset="UTF-8">
         <title>todo</title>
        </head>
        <body>
        <header>
         <h3>待定事項</h3>
        </header>
        <main>
         <ul id="todoList"></ul>
         <input type="text" id="content">
         <button id="confirm">確認</button>
        </main>
        
        <script>
         (function () {
         const ADD_KEY = '__todoList__'
        
         const Utils = {
         // 模擬 Modal(實體模型)
         store(key, data) {
         if (arguments.length > 1) {
         return localStorage.setItem(key, JSON.stringify(data));
         } else {
         let storeData = localStorage.getItem(key);
         return (storeData && JSON.parse(storeData)) || []; // 這里一定要設置初始值為 []
         }
         }
         }
        
         class Todo {
         constructor(id, text = "") {
         this.id = id
         this.text = text
         }
         }
        
         let App = {
         init() {
         // this.todos 為一個存儲json對象的數組, 是一個實例化的數據對象,可任意調用
         this.todos = Utils.store(ADD_KEY)
         this.findDom()
         this.bindEvent()
         this.render() // 初始化渲染
         },
        
        
         findDom() {
         this.contentBox = document.querySelector("#content")
         this.confirm = document.querySelector("#confirm")
         this.todoList = document.querySelector("#todoList")
         this.todoListItem = document.getElementsByTagName("li")
         },
        
         // 模擬 Controller (業務邏輯層)
         bindEvent() {
         this.confirm.addEventListener('click', () => {
         // 要求模型 M 改變狀態,add()函數是寫入數據操作
         this.add()
         }, false)
        
         this.todoList.addEventListener('click', (item) => { // 事件委托,優化性能
         this.remove(item)
         }, false)
         },
        
         // 這里勉強抽象成一個視圖吧!!!
         view() {
         let fragment = document.createDocumentFragment() // 減少回流次數
         fragment = ''
        
         for (let i = 0; i < this.todos.length; i++) { // 一次性DOM節點生成
         // 這里使用拼接字符串代替視圖的模板,
         // *******注意模板并不是一個視圖,模板是由視圖定義配置出來的,并被其管理著*******
         // 模板是用一種聲明的方式指定部分甚至所有的視圖對象
         fragment += `<li>${this.todos[i].text}</li>`
         }
         this.todoList.innerHTML = fragment
         },
        
         // render()函數作為一個訂閱者的回調函數,數據的變化會反饋到模型 store
         // 換句話說:視圖通過觀察者模式,觀察模型 store,當模型發生改變,觸發視圖更新
         render() {
         this.view()
        
         /**
         * 這里需要特別提一下,按照 MVC 原則這里本不應該出現下面的代碼的
         * 因為業務邏輯關系(我本地存儲使用的是同一個key值,再次寫入數據會覆蓋原來的數據,),
         * 所以必須通知模型 M 保存數據, V 層處理了不該它處理的邏輯,導致 M 與 V 耦合
         *
         * 解決辦法是:將其抽象出來編寫一個 視圖助手 helper
         */
         Utils.store(ADD_KEY, this.todos)
         },
        
         getItemIndex(item) {
         let itemIndex
         if (item.target.tagName.toLowerCase() === 'li') {
         let arr = Array.prototype.slice.call(this.todoListItem)
         let index = arr.indexOf(item.target)
         return itemIndex = index
         }
         },
        
         add(e) {
         let id = Number(new Date())
         let text = this.contentBox.value
         let addTodo = new Todo(id, text)
         this.todos.unshift(addTodo) // 模型發生改變
         this.render() // 當模型發生改變,觸發視圖更新
         },
        
         remove(item) {
         let index = this.getItemIndex(item)
         this.todos.splice(index, 1)
         this.render()
         }
         }
        
         App.init()
         })()
        </script>
        </body>
        </html>

        隨著界面和邏輯的復雜,用js或者jq去控制DOM是不現實的。上邊例子只是用原生js模擬mvc的思想實現過程。真正地項目往往會依賴一些封裝好的優秀庫進行高效開發。

        mvc模式的優點

        mvc編程把所有精力放在數據處理,盡可能減少對網頁元素的處理。對于有一定數量功能的網頁,Mvc模式下強制規范代碼,簡化,減少重復代碼,使代碼易于擴充。

        mvc模式的弊端

        1、清晰的構架以代碼的復雜性為代價, 對小項目反而降低開發效率。 (如果本文的例子todoList用面條式代碼編寫,那得多簡單啊?。。。?br /> 2、控制層和視圖層耦合,導致沒有真正分離和重用

        3、在同一業務邏輯下,如果存在多種視圖呈現,需要視圖定義配置多個模板引擎、數據解析,多次處理數據與頁面更新。代碼就充滿了各種選擇器與事件回調,隨著業務的膨脹,變得難以維護。

        總結:其實,現在MVC在前端用得比較少了,因為它的局限性,催生了MVVM模式的流行與廣泛使用,在下篇文章我會談談我對MVVM的理解,以及為何我使用基于MVVM模式的vue框架來高效開發。

        以上這篇老生常談js中的MVC就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        老生常談js中的MVC

        老生常談js中的MVC:MVC是什么? MVC是一種架構模式,它將應用抽象為3個部分:模型(數據)、視圖、控制器(分發器)。 本文將用一個經典的例子todoList來展開(代碼在最后)。 一個事件發生的過程(通信單向流動): 1、用戶在視圖 V 上與應用程序交互 2、控制器 C 觸發相
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 久久久亚洲欧洲日产国码二区| 免费国产草莓视频在线观看黄| 中文字幕无码精品亚洲资源网久久 | 午夜免费啪视频在线观看| 久久夜色精品国产亚洲| 中文成人久久久久影院免费观看| 日韩欧毛片免费视频| 亚洲第一页在线播放| 国产国产人免费人成成免视频 | 亚洲第一页在线播放| 在线观看免费高清视频| 亚洲老熟女五十路老熟女bbw| 四虎影视www四虎免费| 亚洲理论电影在线观看| 亚洲欧美成aⅴ人在线观看| 日韩免费视频在线观看| 中文字幕亚洲综合精品一区| 九九九精品视频免费| 韩国欧洲一级毛片免费| 亚洲成色999久久网站| 免费观看激色视频网站bd| 国产亚洲精品拍拍拍拍拍| 国产一精品一av一免费爽爽| 亚洲视频欧洲视频| 日韩中文无码有码免费视频 | 亚洲不卡影院午夜在线观看| 又粗又硬又黄又爽的免费视频 | 精品国产日韩亚洲一区在线| 亚洲伊人成无码综合网 | 亚洲av片一区二区三区| 老司机69精品成免费视频| 亚洲AV无码久久久久网站蜜桃 | 亚洲午夜无码AV毛片久久| 国产免费拔擦拔擦8X高清在线人| 亚洲日本香蕉视频观看视频| 色www永久免费视频| a毛片免费全部播放完整成| 国产成人精品亚洲2020| 亚洲中文久久精品无码ww16| 妻子5免费完整高清电视| 中文字幕在线视频免费观看|