js手写MVC模式

2023-11-01

效果图如下:
在这里插入图片描述
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .personalData {
      display: none;
    }
  </style>
</head>
<body>
  <div class="dataInputArea">
    <div>
      <span>请输入个人的姓名</span>
      <input type="text" placeholder="姓名" class="nameData">
    </div>
    <div>
      <span>请输入个人的年龄</span>
      <input type="text" placeholder="年龄" class="ageData">
    </div>
    <div>
      <span>请输入个人的特长</span>
      <input type="text" placeholder="特长" class="specData">
    </div>
    <div class="personalData">
      <p>
        本人: <span class="name">王大少</span>,今年芳龄 <span class="age">0</span>,擅长 <span class="spec">吃饭</span>
      </p>
    </div>
  </div>
  <script>
	 //MVC模式
    class MVC {
      constructor (options) {
        this.model = options.model    //获取操作元素 负责事件的订阅与发布
        this.controller = options.controller  //事件绑定并订阅事件
        this.view = options.view      //更新页面数据
        this.controller.bundle(this)  //激活控制器
      }
    }
    let mvc = new MVC({
      model: {
        data: {
          vNameObj: document.querySelector('.nameData'),
          vAgeObj: document.querySelector('.ageData'),
          vSpecObj: document.querySelector('.specData'),
          oName: document.querySelector('.name'),
          oAge: document.querySelector('.age'),
          oSpec: document.querySelector('.spec'),
          oPersonal: document.querySelector('.personalData'),
          nameValue: 0,
          ageValue: 0,
          specValue: 0
        },
        observe: {
          clientList: {},
          //订阅
          listen (key, fn) {
            if (!this.clientList[key]) {
              this.clientList[key] = []
            }
            this.clientList[key].push(fn)
          },
          //发布
          trigger () {
            //获取第一个参数 发布的函数数组键名
            let key = Array.prototype.shift.call(arguments)
            let fns = this.clientList[key]
            if (!fns || fns.length === 0) {
              return false
            }
            for (let i=0, fn; fn =fns[i++];) {
              fn.apply(this,arguments)
            }
          },
          update (o, key, value) {  //(MVC的this, '发布事件名', '改变的值')
            let valueKey = '',
                targetKey = '';
            switch (key) {
              case 'vNameObj':
                valueKey = "nameValue" //数据内容变量
                targetKey = "oName"    //对应标签
                break;
              case 'vAgeObj':
                valueKey = "ageValue"
                targetKey = "oAge"
                break;
              case 'vSpecObj':
                valueKey = "specValue"
                targetKey = "oSpec"
                break;
            }
            //更改MVC的this内的nameValue,ageValue,specValue值
            o.model.data[valueKey] = value
            //发布事件oName,oAge,oSpec
            o.model.observe.trigger(targetKey, value)
          }
        }
      },
      controller: {
        bundle (o) {  //o指向MVC的this
          let that = o
          //给input标签添加监听事件
          that.model.data.vNameObj.oninput = function () {
            //通过更新事件 刷新数据(MVC的this, '发布事件名', '改变的值')
            that.model.observe.update(that, "vNameObj", this.value)
          }
          that.model.data.vAgeObj.oninput = function () {
            that.model.observe.update(that, "vAgeObj", this.value)
          }
          that.model.data.vSpecObj.oninput = function () {
            that.model.observe.update(that, "vSpecObj", this.value)
          }

          //订阅事件oName,oAge,oSpec
          that.model.observe.listen("oName", function (value) {
            that.view.update(that, "oName", value)
          })
          that.model.observe.listen("oAge", function (value) {
            that.view.update(that, "oAge", value)
          })
          that.model.observe.listen("oSpec", function (value) {
            that.view.update(that, "oSpec", value)
          })
        }
      },
      view: {
        update (o, targetKey, value) {
          let that = o
          //给页面标签设置内容
          that.model.data[targetKey].innerText = value,
          {nameValue, ageValue, specValue, oPersonal} = that.model.data;
          //监听.oPersonal标签是否显示
          if (nameValue && ageValue && specValue) {
            oPersonal.style.display = "block"
          } else {
            oPersonal.style.display = "none"
          }
        }
      }
    })
    /* MVC原理:
    controller.bundle()绑定订阅事件 ——> 输入触发oninput事件
    ——> model.observe.update发布订阅事件 ——>执行对应订阅的事件
    ——> view.update() 修改页面对应数据
    */

    /*  普通模式
    let vNameObj = document.querySelector('.nameData'),
        vAgeObj= document.querySelector('.ageData'),
        vSpecObj = document.querySelector('.specData'),
        oName = document.querySelector('.name'),
        oAge = document.querySelector('.age'),
        oSpec = document.querySelector('.spec'),
        oPersonal = document.querySelector('.personalData'),
        nameValue, ageValue, specValue;

    //   Controller控制模块
    vNameObj.onchange = function (ev) {
      nameValue = this.value
      setObjInnerText(oName, nameValue)
    }
    vAgeObj.onchange = function (ev) {
      ageValue = this.value
      setObjInnerText(oAge, ageValue)
    }
    vSpecObj.onchange = function (ev) {
      specValue = this.value
      setObjInnerText(oSpec, specValue)
    }

    //    view视图模块
    function setObjInnerText(obj, value) {
      obj.innerText = value
      if (nameValue && ageValue && specValue) {
        oPersonal.style.display = "block"
      } else {
        oPersonal.style.display = "none"
      }
    }
    */
  </script>
</body>
</html>

逻辑结构图如下:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js手写MVC模式 的相关文章

随机推荐

  • 如何正确应用GNU GPLv3 和 LGPLv3 协议

    文章目录 前言 GNU GPLv3 0 Permissions 许可 Conditions 条件 Limitations 限制 GNU LGPLv3 0 应用GPLv3 0 应用LGPLv3 0 建议的内容 添加文件头声明 附录 GNU G
  • 让更多消费者接受刷脸支付养成刷脸习惯

    扫码支付能够取代现金和刷卡支付 就是基于其便捷的支付体验 消费者只要带上手机 用手机扫码就可以完成支付 免去了许多携带现金或卡的不便 降低了遗失风险 但是扫码支付也是过度依赖了手机这一媒介 在手机忘带和没电的时候 也是束手无策 基于此 刷脸
  • 慢SQL语句优化

    对慢SQL语句优化一般可以按下面几步思路 开启慢查询日志 设置超过几秒为慢SQL语句 抓取慢SQL语句 通过explain查看执行计划 对慢SQL语句分析 创建索引并调整语句 再查看执行计划 对比调优结果 参数 slow query log
  • git版本库创建三部曲(git权威指南笔记)

    1 全局配置 a 告诉git当前用户的姓名和邮箱 git config global user name heaiming git config global user email 576439313 qq com b 设置git命令别名
  • CSS改变layui时间控件不显示秒

    laydate time list gt li last child display none width 0 laydate time list gt li not last child width 50 layui laydate ma
  • Win7系统安装哪个版本的Chrome浏览器

    Win系统安装Chrome浏览器 Win7系统环境 安装Chrome应该尽量考虑2021年发布的浏览器版本 理由如下 Win7版Chrome 续命 到2022年 延长支持6个月 Win7版Chrome 续命 到2022年 90版本Chrom
  • starting switch Root:systemd [1]: Failed to execute /bin/sh, giving up : No such file or directory

    启动centos 卡在starting switch Root starting switch Root systemd 1 Failed to execute bin sh giving up No such file or direct
  • LeetCode第二章链表

    203 移除链表元素 题目链接 203 移除链表元素 给你一个链表的头节点 head 和一个整数 val 请你删除链表中所有满足 Node val val 的节点 并返回 新的头节点 示例 1 输入 head 1 2 6 3 4 5 6 v
  • C++初始化参数列表(类的组合)

    A 类的组合 定义 类的组合就是以另一个的对象为数据成员 注意 要优先使用组合而不是继承 组合表达式的含义一部分的关系 类的组合案例分析 1 类组合包含的类的对象 必须采用初始化参数列表方式调用各自类当中的构造函数去初始化 2 要通过包含的
  • 用户级线程和内核级线程

    用户级线程和内核级线程 根据在用户空间还是在核心实现多线程机制 线程又被分为用户级线程 User Level Thread 和内核级线程 Kernel Level Thread
  • 文件操作【上篇】

    文章目录 1 为什么使用文件 2 什么是文件 2 1 程序文件 2 2 数据文件 2 3 文件名 3 文件的打开和关闭 3 1 文件指针 3 2 文件的打开和关闭 4 文件的顺序读写 4 1 fputc 写文件 4 2 fgetc 读文件
  • 【再回首Python之美】【模块 math】math模块的基本使用

    学好数理化 走遍天下都不怕 所以一定要把Python的math模块学好 math简介 math提供两个数学常量和众多数学函数 这俩常量和众多数学函数都是哪些呢 通过dir math 一看便知 使用math模块之前 一定要把模块包括进来 告诉
  • 关于Jenkins插件无法更新的问题

    由于Jenkins默认的更新站点服务器在国外 所以国内使用时需要翻墙 下面整理了一些国内的镜像站点 可以将更新站点修改后 进行相关插件的更新 国内镜像站点 站点一 实测通过 http mirror xmission com jenkins
  • ipad连接电脑_躺在被窝玩电脑,利用ipone ipad远程控制局域网电脑

    时光荏苒 人生的旅途来到了2019年 小科祝愿大家在新的一年里 猪 事顺利 和和美美 冬天 一年中最寒冷的季节 作为一个南方人 对于寒冷是唯恐而不及了 既没有暖气 一天开着空调又太耗电 所以能在床上解决的事情就坚决不下床 今天小科来教大家如
  • python 声音合成,使用python进行声音生成/合成?

    Is it possible to get python to generate a simple sound like a sine wave Is there a module available for this If not how
  • 机械革命蛟龙16ubuntu双系统的移除与重装

    介绍一下本人重装的一个初衷 首先系统更新内核导致cuda无法运行 其次原本的70g空间捉襟见肘 因此想要重装分配更多一些空间 若没有扩容的需求可以去找找系统自带的重装方法 应该会比我下面的流程快很多 1 预备工作 1 1 查看电脑的引导方式
  • 怎么理解分布式、高并发、多线程?(含面试题和答案解析)

    看到分布式 高并发 多线程这三个词的时候 很多人是不是都认为分布式 高并发 多线程 当面试官问到高并发系统可以采用哪些手段来解决 或者被问到分布式系统如何解决一致性的问题 是不是一脸懵逼 确实 在一开始接触的时候 不少人都会分布式 高并发
  • 基于深度学习的道路交通标志数字识别

    基于MATLAB深度学习的交通标志识别 课题介绍 交通标志识别技术的研究最早开始于奔驰等14家大型汽车公 司组成的民间组织所资助的Prometheus Program for European Traffic with Highest Ef
  • 解决mac command 找不到mysql命令

    root DB 02 mysql u root bash mysql command not found 原因 这是由于系统默认会查找 usr bin下的命令 如果这个命令不在这个目录下 当然会找不到命令 我们需要做的就是映射一个链接到 u
  • js手写MVC模式

    效果图如下 代码如下 div class dataInputArea div span 请输入个 span div div