热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

怎樣完成一個MV*形式(MVC/MVP/MVVM)

如果讓你不依託任何前端框架(ReactVueAngular等等),純真用Javascript編寫一個網站運用,你還知道怎樣開闢嗎?舉個例子,產物司理讓你完成一個網頁,上面有一張貓咪

如果讓你不依託任何前端框架(React/Vue/Angular等等),純真用Javascript編寫一個網站運用,你還知道怎樣開闢嗎?

舉個例子,產物司理讓你完成一個網頁,上面有一張貓咪的圖片,貓咪的下面顯現點贊的次數。每次點擊貓咪的圖片,點贊的数字加一。

這個對人人來講應當都很簡樸。

這時刻產物司理最先加需求了,網頁上展現五張貓咪圖片,離別有本身的點贊次數,點擊貓咪圖片,相對應的點贊次數加一。這時刻你想怎樣改寫本身的順序呢?你的順序如今看起來是不是邏輯清楚,構造清楚,可拓展性強呢?

本日我就要帶人人用MV形式來構造代碼,編寫出高質量幽美的前端項目。起首我們要也許搞清楚一些什麼MV形式。

什麼MV*形式

MV*是MVC/MVP/MVVM等的一個統稱,它們各有不同,但本質上實際上是一個東西。MVP和MVVM是MVC的變體。所以我們本日不議論它們的區分,只關注中心的東西。

M代表的是Model,用於封裝與運用順序的營業邏輯相干的數據以及對數據的處置懲罰要領。Model有對數據直接接見的權利,比方對數據庫的接見。Model 不體貼它會被怎樣顯現或是怎樣被操縱。

V代表的是View,用於將數據有目標的顯現出來,在 View 中平常沒有順序上的邏輯。

末了的*,不管是Controller照樣Presenter,照樣ViewModel,本質上做的事變就是銜接M和V,搭建M和V溝通的橋樑。讓M和V不直接溝通,到達職責星散的結果。

我們能夠看維基百科上一個極簡的MVC完成:

/** 模仿 Model, View, Controller */
var M = {}, V = {}, C = {};
/** Model 擔任寄存材料 */
M.data = "hello world";
/** View 擔任將材料顯現到屏幕上 */
V.render = (m) => { alert(m.data); }
/** Controller 作為一個 M 和 V 的橋樑 */
C.handleOnload= () => { V.render(M); }
/** 在網頁讀取的時刻挪用 Controller */
window.Onload= C.handleOnload;

我們本日要完成的MV*就要滿足這幾個前提:

  1. Model保留我們的數據
  2. View擔任襯着節點,能夠有多個View
  3. *(我們給它取個名字叫Bridge)為View供應讀取和修正Model的要領

產物司理的需求

最終版:網頁左邊展現一個可挑選的貓咪名字列表,右邊展現當前選中的貓咪概況,包含貓咪稱號,貓咪圖片,該貓咪被點贊數目和一個點贊按鈕。點擊點贊按鈕,當前貓咪的點贊數目加1。結果圖以下,我們只體貼功用完成,所以款式丑我們先忍一下。

《怎樣完成一個MV*形式(MVC/MVP/MVVM)》

HTML && CSS





    placekitten


    👏


    構造很清楚,主要有一個id是cat-list的貓咪列表和一個id是cat-container的貓咪概況,貓咪概況包含三部份,貓咪名字,貓咪圖片和點贊區。增加一點簡樸的款式。

    #main {
    display: flex;
    }
    #cat-list {
    flex: 0 0 100px;
    }
    #cat-list li {
    cursor: pointer;
    }
    #cat-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    }
    #cat-img {
    width: 300px;
    height: 300px;
    }
    #likes-btn {
    cursor: pointer;
    }

    Model

    let model = {
    currentCat: null,
    cats: [
    {
    title: '我是一號喵喵',
    imageSrc: 'https://placekitten.com/300/300',
    likesCount: 0
    },
    {
    title: '我是二號喵喵',
    imageSrc: 'https://placekitten.com/301/301',
    likesCount: 0
    },
    {
    title: '我是三號喵喵',
    imageSrc: 'https://placekitten.com/302/302',
    likesCount: 0
    },
    {
    title: '我是四號喵喵',
    imageSrc: 'https://placekitten.com/303/303',
    likesCount: 0
    }
    ]
    };

    我們的數據包含兩部份,currentCat示意當前展現的貓咪概況對象, cats示意貓咪列表。能夠看出我們如今的Model就是純真的數據展現,沒有任何與展現相干的邏輯,將來拓展起來異常輕易。

    Bridge

    方才說了Bridge要擔任為View供應一切對Model數據的讀取和修正的要領。所以我們能夠思索下,有哪些要領須要供應。

    1. 起首要供應一個Init的要領,實行初次襯着view的事情
    2. 獵取當前挑選的貓咪概況
    3. 才列表挑選要閱讀的貓咪
    4. 獵取貓咪列表
    5. 為當前挑選的貓咪點贊

    let brain = {
    init: () => {
    model.currentCat = model.cats[0]; //初始化 catListView.init(); //這兩個View稍後供應
    catView.init();
    },
    getCurrentCat: () => model.currentCat,
    setCurrentCat: (cat) => {
    model.currentCat = cat;
    catView.render(); // 手動觸發View從新襯着,這是將來我們的主要優化點
    },
    getCats: () => model.cats,
    incrementLikes: () => {
    model.currentCat.likesCount++;
    catView.render(); // 手動觸發View從新襯着,這是將來我們的主要優化點
    }
    };

    View

    我們有兩個View,一個是貓咪列表catListView, 另一個是貓咪概況catView。

    let catView = {
    init: function () {
    this.catTitle = document.getElementById('cat-title');
    this.catImg = document.getElementById('cat-img');
    this.likesCount = document.getElementById('likes-count');
    this.likesBtn = document.getElementById('likes-btn'); this.likesBtn.addEventListener('click', () => {
    brain.incrementLikes();
    }) this.render()
    },
    render: function () {
    let currentCat = brain.getCurrentCat();
    this.catTitle.textCOntent= currentCat.title;
    this.catImg.src = currentCat.imageSrc;
    this.likesCount.textCOntent= currentCat.likesCount;
    }
    }

    注意到,我們把init和render拆成兩個要領。

    init要領起首把相干的DOM節點先保留下來,防止後續每次還得從新尋覓DOM節點;然後為點贊按鈕綁定點擊事宜,點擊時挪用brain供應的incrementLikes要領修正Model;末了實行render完成初次襯着。

    而render函數儘管襯着,每次挪用都邑直接修正DOM節點,更新襯着。

    let catListView = {
    init: function () {
    this.catListElem = document.getElementById('cat-list');
    this.render();
    },
    render: function () {
    let cats = brain.getCats(); cats.forEach(cat => {
    let catElem = document.createElement('li');
    catElem.textCOntent= cat.title;
    catElem.addEventListener('click', () => {
    brain.setCurrentCat(cat);
    })
    this.catListElem.appendChild(catElem)
    })
    }
    }

    catListView構造與上面相似。

    設置完model, brain, catlistview, catview四個對象后,我們在末了挪用brain.init()就完成了一切事情。

    末了

    本日我們就完成了一個MV形式,它基本上歸納綜合了MV形式的中心。然則遺留了一個很主要的題目:每當我們數據修正的時刻,我們都手動挪用了一下view的render函數來從新襯着頁面,如許顯然是不智慧的。下期我們細緻研究一下MVVM的代表Backbone, knockout等等以及Vue是怎樣完成他們的MV*。


    推荐阅读
    • 本文详细介绍如何在VSCode中配置自定义代码片段,使其具备与IDEA相似的代码生成快捷键功能。通过具体的Java和HTML代码片段示例,展示配置步骤及效果。 ... [详细]
    • 本文介绍了如何利用npm脚本和concurrently工具,实现本地开发环境中多个监听服务的同时启动,包括HTTP服务、自动刷新、Sass和ES6支持。 ... [详细]
    • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
      本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
    • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
    • 本文详细介绍了在企业级项目中如何优化 Webpack 配置,特别是在 React 移动端项目中的最佳实践。涵盖资源压缩、代码分割、构建范围缩小、缓存机制以及性能优化等多个方面。 ... [详细]
    • 本文探讨了在使用Selenium进行自动化测试时,由于webdriver对象实例化位置不同而导致浏览器闪退的问题,并提供了详细的代码示例和解决方案。 ... [详细]
    • 深入理解Vue.js:从入门到精通
      本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
    • Redux入门指南
      本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
    • 本文详细介绍了如何在Kendo UI for jQuery的数据管理组件中,将行标题字段呈现为锚点(即可点击链接),帮助开发人员更高效地实现这一功能。通过具体的代码示例和解释,即使是新手也能轻松掌握。 ... [详细]
    • SpringMVC RestTemplate的几种请求调用(转)
      SpringMVCRestTemplate的几种请求调用(转),Go语言社区,Golang程序员人脉社 ... [详细]
    • 在使用 MUI 框架进行应用开发时,开发者常常会遇到 mui.init() 和 mui.plusReady() 这两个方法。本文将详细解释它们的区别及其在不同开发环境下的应用。 ... [详细]
    • 前端开发:从底层到顶端的行业现象解析
      在编程领域,鄙视链现象屡见不鲜,从C语言到Java、.NET等,每个技术栈都有其独特地位。然而,前端开发者尽管常处于鄙视链底端,却在市场需求中备受青睐。本文深入探讨这一现象,并分析前端工程师如何在竞争激烈的市场中脱颖而出。 ... [详细]
    • 在使用 Vue CLI 创建的项目中,引入样式模块(CSS Module)后,发现类名被自动修改。本文将详细解释这一现象并提供解决方案。 ... [详细]
    • 使用JS、HTML5和C3创建自定义弹出窗口
      本文介绍如何结合JavaScript、HTML5和C3.js来实现一个功能丰富的自定义弹出窗口。通过具体的代码示例,详细讲解了实现过程中的关键步骤和技术要点。 ... [详细]
    • Vue 开发与调试工具指南
      本文介绍了如何使用 Vue 调试工具,包括克隆仓库、安装依赖包、构建项目以及在 Chrome 浏览器中加载扩展的详细步骤。 ... [详细]
    author-avatar
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有