首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

js mvvm 实现原理

MVVM(Model-View-ViewModel)是一种软件架构模式,主要用于分离用户界面(UI)逻辑和业务逻辑。在JavaScript中,MVVM模式的实现通常依赖于数据绑定和观察者模式。以下是MVVM的基本概念及其在JavaScript中的实现原理:

基础概念

  1. Model(模型):代表应用程序的数据和业务逻辑。
  2. View(视图):用户界面,通常是HTML和CSS的组合。
  3. ViewModel(视图模型):作为Model和View之间的桥梁,负责将Model的数据转换为View可以展示的形式,并处理View的用户交互。

实现原理

数据绑定

数据绑定是MVVM的核心机制,它使得ViewModel中的数据变化能够自动反映到View上,反之亦然。常见的实现方式有:

  • 双向数据绑定:当Model的数据改变时,View会自动更新;当用户在View上进行操作时,Model的数据也会相应更新。

观察者模式

观察者模式用于实现数据绑定。ViewModel会“观察”Model中的数据,一旦数据发生变化,就会通知相关的View进行更新。

优势

  1. 分离关注点:将UI逻辑与业务逻辑分离,使代码更易于维护和测试。
  2. 提高可重用性:ViewModel可以被多个View复用。
  3. 自动化更新:数据的变化能自动同步到UI,减少了手动操作DOM的需要。

类型与应用场景

  • 单向数据流:适用于简单的表单和列表展示。
  • 双向数据绑定:适用于复杂的交互界面,如表单验证、实时搜索等。

实现示例

以下是一个简单的JavaScript MVVM实现示例:

代码语言:txt
复制
class Observable {
  constructor(data) {
    this.data = data;
    this.walk(data);
  }

  walk(obj) {
    const keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++) {
      this.defineReactive(obj, keys[i]);
    }
  }

  defineReactive(obj, key) {
    let val = obj[key];
    const dep = new Dep();
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get() {
        if (Dep.target) {
          dep.addSub(Dep.target);
        }
        return val;
      },
      set(newVal) {
        if (newVal === val) return;
        val = newVal;
        dep.notify();
      }
    });
  }
}

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

Dep.target = null;

class Watcher {
  constructor(vm, exp, cb) {
    this.vm = vm;
    this.exp = exp;
    this.cb = cb;
    this.value = this.get();
  }

  get() {
    Dep.target = this;
    const value = this.vm.data[this.exp];
    Dep.target = null;
    return value;
  }

  update() {
    const oldValue = this.value;
    this.value = this.vm.data[this.exp];
    this.cb.call(this.vm, this.value, oldValue);
  }
}

// 使用示例
const data = { name: 'John' };
const vm = new Observable(data);

new Watcher(vm, 'name', (newValue, oldValue) => {
  console.log(`Name changed from ${oldValue} to ${newValue}`);
});

vm.data.name = 'Jane'; // 输出: Name changed from John to Jane

常见问题及解决方法

问题:数据更新但视图未刷新。

原因:可能是由于数据没有被正确地设置为响应式,或者观察者没有正确地监听到数据变化。

解决方法

  • 确保所有需要响应的数据都通过Observable类进行了包装。
  • 检查Watcher是否正确地设置了依赖,并且在数据变化时能够触发更新。

通过这种方式,MVVM模式能够有效地提升开发效率和应用的可维护性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【JS】508- MVVM原理介绍

划重点 MVVM 双向数据绑定 在Angular1.x版本的时候通过的是脏值检测来处理 而现在无论是React还是Vue还是最新的Angular,其实实现方式都更相近了 那就是通过数据劫持+发布订阅模式...--实现的mvvm--> mvvm.js"> // 写法和Vue一样 let mvvm =..._data.a.b这种,我们其实可以直接写成mvvm.a.b这种显而易见的方式 下面继续看下去,+号表示实现部分 function Mvvm(options = {}) { // 数据劫持...= 'ok'; console.log(mvvm.a.b); // 'ok' 写到这里数据劫持和数据代理都实现了,那么接下来就需要编译一下了,把{{}}里面的内容解析出来 数据编译 function...mvvm一共包含了以下东西 通过Object.defineProperty的get和set进行数据劫持 通过遍历data数据进行数据代理到this上 通过{{}}对数据进行编译 通过发布订阅模式实现数据与视图同步

1K40

深度解析 Vue MVVM 原理实现

什么是MVVM?...之所以能做到这一点,主要是依靠 Vue 框架才得以实现的。 如图: ? MVVM原理 上面已经说了, View层和Model层并没有直接联系,而是通过ViewModel层进行交互。...实现数据绑定的做法有大致如下几种: 脏值检查(angular.js) 数据劫持(vue.js) 发布者-订阅者模式(backbone.js) 这里大致说下脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更...要实现mvvm的双向绑定,就必须要实现以下几点: 1.实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 2.实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析...实现MVVM <!

1.5K20
  • 剖析Vue原理&实现双向绑定MVVM

    1、了解vue的双向数据绑定原理以及核心代码模块 2、缓解好奇心的同时了解如何实现双向绑定 为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,相对较简陋,并未考虑到数组的处理、.../js/mvvm.js"> var vm = new MVVM({ el: '#mvvm-app', data: {...实现数据绑定的做法有大致如下几种: 发布者-订阅者模式(backbone.js) 脏值检查(angular.js) 数据劫持(vue.js) 发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听...一个简单的MVVM模块已经实现,其思想和原理大部分来自经过简化改造的vue源码,在这里https://github.com/DMQ/mvvm可以看到本文的所有相关代码。...总结 本文主要围绕“几种实现双向绑定的做法”、“实现Observer”、“实现Compile”、“实现Watcher”、“实现MVVM”这几个模块来阐述了双向绑定的原理和实现。

    3.1K70

    MVVM --- 实现多层级通知

    现有的MVVM框架,例如 MVVMLight ,Prism 等框架, 我好像都没有找到这样的功能,如果有更好的方案或实现,烦请告之。 现在手动实现一个这样的辅助类。...接下来看一下实现过程: INotifyHolder接口 先定义 INotifyHolder 接口,用于通知 HolderViewModel ,有属性变化了。...}; } } } } } } 这个类就是实现这个功能的核心...,其主要原理是,通过 NoticeFlagAttribute 特性,获取你要绑定的属性,然后 监控你要绑定的属性的 INotifyPropertyChanged 的PropertyChanged 事件或者是...HolderViewModel 中,若子属性有多层级关系,可以多层级中每个层级使用 NoticeFlagAttribute 特性,标记你想要监控的属性,然后Binding管理器通过递归方式依次绑定好,就实现了多层级的监控通知到

    16710

    Android MVVM 架构应用实现

    以前项目中虽然也使用MVVM架构,但由于整体框架不是我自己搭建的,导致我对于MVVM架构的整体还是很不熟悉,所以这次就自己搭建并实现一次MVVM架构。...MVVM架构使用的组件有ViewModel、LiveData、ViewBinding/DataBinding等,这些组件都是Jetpack库中的组件。...[MVVM架构图] 了解了MVVM的基本架构和其中各个组件的作用,可以开始代码实现了。我做这个项目的初衷是因为最近在整理收集Android常用的开源库,为了更方便的展示所实现的一个应用。...先贴上项目目录,需要关注的是高亮显示的文件(使用Koin省去了Factory类的实现): [image.png] ViewModel类: 实现HomeViewModel类,需要继承继承自ViewModel...架构的应用搭建完成,第一次独立的搭建MVVM架构之后,对于MVVM架构的理解加深了不少,对于JetPack库中的组件和其它开源库也有了新的认识,此外MVVM架构还经常和Retrofit、RxJava等开源库配合使用

    1.3K20

    MVVM模式和在WPF中的实现(一)MVVM模式简介

    再后来接触到了MVVM,更加体会到了以MVVM模式开发WPF带来的好处。现在除非要求已经不再用Winform了,小工具和测试程序直接在后台写代码,复杂一点的需要长期使用和维护的用MVVM模式。...这个系列的文章主要写一下自己对MVVM的理解和核心部分的简易实现方式。...0x01 MVVM模式简介 MVVM是Model、View、ViewModel的简写,这种模式的引入就是使用ViewModel来降低View和Model的耦合,说是降低View和Model的耦合。...0x02 WPF中MVVM的解耦方式 在WPF的MVVM模式中,View和ViewModel之间数据和命令的关联都是通过绑定实现的,绑定后View和ViewModel并不产生直接的依赖。...0x3 MVVM框架需要解决的问题 从图中可以看出如果要实现一套MVVM框架,需要解决的最基本的问题就是数据绑定和命令绑定。此外由于UI中会产生大量的事件,因此还需要将事件绑定到MVVM中的命令上。

    1.6K20

    flutter鸿蒙版本mvvm架构思想原理

    写在前面 在Flutter中实现MVVM(Model-View-ViewModel)架构是为了将UI(视图)与业务逻辑(模型和视图模型)分离,提高代码的可维护性和可读性。 1....CounterViewModel类: 继承自ChangeNotifier,实现了观察者模式,使得UI组件能够监听到数据的变化。...原理的说明:Dart'), Text('页面MyHomePage向中间层CounterViewModel要数据'),//业务层(负责直接面对用户的一层)...显示一些文本以说明MVVM的工作原理,并动态展示计数值。 使用FloatingActionButton调用incrementCounter方法以增加计数值。 2.4....写在最后 在Flutter中实现MVVM架构的关键在于利用Provider进行状态管理,将数据和UI分开,使得应用程序的各个部分相互独立,增强了可维护性和可测试性。

    11210

    flutter鸿蒙版本mvvm架构思想原理

    写在前面在Flutter中实现MVVM(Model-View-ViewModel)架构是为了将UI(视图)与业务逻辑(模型和视图模型)分离,提高代码的可维护性和可读性。1....CounterViewModel类:继承自ChangeNotifier,实现了观察者模式,使得UI组件能够监听到数据的变化。...原理的说明:Dart'), Text('页面MyHomePage向中间层CounterViewModel要数据'),//业务层(负责直接面对用户的一层) Text...显示一些文本以说明MVVM的工作原理,并动态展示计数值。使用FloatingActionButton调用incrementCounter方法以增加计数值。2.4....写在最后在Flutter中实现MVVM架构的关键在于利用Provider进行状态管理,将数据和UI分开,使得应用程序的各个部分相互独立,增强了可维护性和可测试性。

    6200

    JS实现无限分页加载——原理图解

    由于网页的执行都是单线程的,在JS执行的过程中,页面会呈现阻塞状态。因此,如果JS处理的数据量过大,过程复杂,可能会造成页面的卡顿。...本篇就无限分页的实现模型,讲述其中奥妙。 原理图 实现无限分页的过程大致如下: 1 视窗滚动到底部 2 触发加载,添加到现有内容的后面。...实现的思路: 1 如果真实的内容比视窗高度小,则一直加载到超过视窗 2 如果超过了视窗,则判断下面隐藏的部分的距离是否小于一定的值,如果是,则触发加载。...content="text/html; charset=utf-8" /> js...clientHeight、scrollHeight、offsetHeight区别 【2】ScrollHeight、OffsetHeight、ClientHeight 【3】CSS position 属性 【4】《JS

    6K100

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券