当前位置:首页 > JavaScript

js实现mvvm

2026-04-07 05:21:45JavaScript

MVVM 模式简介

MVVM(Model-View-ViewModel)是一种前端架构模式,核心思想是将视图(View)与业务逻辑(ViewModel)解耦,通过数据绑定实现双向同步。Model 管理数据,View 负责渲染,ViewModel 作为桥梁处理逻辑和状态。

实现 MVVM 的关键技术

  1. 数据劫持(响应式数据)
    通过 Object.definePropertyProxy 监听数据变化,触发更新。

    // 使用 Proxy 实现响应式
    function reactive(obj) {
      return new Proxy(obj, {
        get(target, key) {
          return target[key];
        },
        set(target, key, value) {
          target[key] = value;
          updateView(); // 触发视图更新
          return true;
        }
      });
    }
  2. 模板编译
    解析 HTML 模板中的指令(如 v-model{{}}),替换为动态数据并绑定事件。

    function compile(template, data) {
      return template.replace(/\{\{(.*?)\}\}/g, (_, key) => {
        return data[key.trim()];
      });
    }
  3. 依赖收集与发布订阅
    为每个数据属性维护一个依赖列表(Dep),当数据变化时通知所有依赖(Watcher)更新。

    js实现mvvm

    class Dep {
      constructor() {
        this.subscribers = [];
      }
      depend() {
        if (Watcher.target) this.subscribers.push(Watcher.target);
      }
      notify() {
        this.subscribers.forEach(watcher => watcher.update());
      }
    }

完整实现示例

class MVVM {
  constructor(options) {
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.observe(this.$data);
    this.compile(this.$el);
  }

  observe(data) {
    Object.keys(data).forEach(key => {
      let value = data[key];
      const dep = new Dep();
      Object.defineProperty(data, key, {
        get() {
          if (Watcher.target) dep.depend();
          return value;
        },
        set(newVal) {
          value = newVal;
          dep.notify();
        }
      });
    });
  }

  compile(node) {
    Array.from(node.childNodes).forEach(child => {
      if (child.nodeType === 3) { // 文本节点
        const text = child.textContent;
        const reg = /\{\{(.*?)\}\}/g;
        if (reg.test(text)) {
          const key = RegExp.$1.trim();
          new Watcher(this.$data, key, () => {
            child.textContent = text.replace(reg, this.$data[key]);
          });
        }
      } else if (child.nodeType === 1) { // 元素节点
        Array.from(child.attributes).forEach(attr => {
          if (attr.name === 'v-model') {
            const key = attr.value;
            child.value = this.$data[key];
            child.addEventListener('input', e => {
              this.$data[key] = e.target.value;
            });
            new Watcher(this.$data, key, () => {
              child.value = this.$data[key];
            });
          }
        });
        this.compile(child);
      }
    });
  }
}

class Watcher {
  constructor(data, key, cb) {
    Watcher.target = this;
    this.cb = cb;
    data[key]; // 触发 getter,收集依赖
    Watcher.target = null;
  }
  update() {
    this.cb();
  }
}

使用示例

<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>

<script>
  const vm = new MVVM({
    el: '#app',
    data: { message: 'Hello MVVM!' }
  });
</script>

优化方向

  1. 虚拟 DOM:减少直接 DOM 操作,通过 diff 算法批量更新。
  2. 指令扩展:支持 v-forv-if 等复杂指令。
  3. 性能优化:避免不必要的依赖触发,如计算属性缓存。

通过以上实现,可以构建一个基础的 MVVM 框架,类似 Vue 的响应式原理。

标签: jsmvvm
分享给朋友:

相关文章

jquery.js

jquery.js

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互等操作。以下是关于 jQuery.js 的核心信息和使用方法: 获取 jQ…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点可…

js图片轮播的实现

js图片轮播的实现

基础图片轮播实现 使用HTML、CSS和JavaScript实现一个简单的图片轮播效果。HTML部分定义轮播容器和图片,CSS负责样式和过渡效果,JavaScript处理逻辑。 <div cl…

js图片上传实现

js图片上传实现

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API实现基础图片上传功能。HTML部分需要设置accept="image/…

js实现 拖动

js实现 拖动

实现拖动的步骤 HTML 结构 创建一个可拖动的元素和一个放置区域: <div id="draggable" draggable="true">拖动我</div> <d…

js 实现文件上传

js 实现文件上传

文件上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现文件上传功能。以下是一个基础示例: <input ty…