当前位置:首页 > JavaScript

js实现mvvm

2026-03-15 11:53:29JavaScript

MVVM 模式简介

MVVM(Model-View-ViewModel)是一种前端架构模式,通过数据绑定实现视图(View)与数据模型(Model)的分离。ViewModel 作为中间层,负责处理业务逻辑和数据转换,View 自动响应数据变化。

核心实现步骤

数据劫持(响应式数据)

使用 Object.definePropertyProxy 监听数据变化,触发更新逻辑。

// Proxy 实现  
const data = { text: 'Hello' };
const reactiveData = new Proxy(data, {
  set(target, key, value) {
    target[key] = value;
    updateView(); // 触发视图更新  
    return true;
  }
});

模板编译

解析 HTML 模板中的指令(如 v-model{{}}),将动态数据与 DOM 绑定。

function compile(template) {
  const el = document.querySelector(template);
  const nodes = el.childNodes;
  nodes.forEach(node => {
    if (node.nodeType === 3) { // 文本节点  
      const text = node.textContent;
      const reg = /\{\{(.*?)\}\}/g;
      if (reg.test(text)) {
        const key = RegExp.$1.trim();
        node.textContent = data[key]; // 初始化数据  
        // 监听变化,更新视图  
        watch(key, (newVal) => {
          node.textContent = newVal;
        });
      }
    }
  });
}

依赖收集与观察者

通过 Dep(依赖管理器)和 Watcher(观察者)实现数据变更时的精准更新。

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(watcher) {
    this.subs.push(watcher);
  }
  notify() {
    this.subs.forEach(watcher => watcher.update());
  }
}

class Watcher {
  constructor(key, updateFn) {
    this.key = key;
    this.updateFn = updateFn;
    Dep.target = this; // 全局暂存 Watcher  
    this.updateFn();   // 触发 getter 收集依赖  
    Dep.target = null;
  }
  update() {
    this.updateFn();
  }
}

双向绑定(v-model)

将表单输入与数据模型同步,通常通过事件监听实现。

function bindInput(modelKey) {
  const input = document.querySelector(`[v-model="${modelKey}"]`);
  input.addEventListener('input', (e) => {
    reactiveData[modelKey] = e.target.value; // 触发 Proxy.set  
  });
}

完整示例

整合上述模块,实现一个简易 MVVM:

js实现mvvm

class MiniMVVM {
  constructor(options) {
    this.$el = document.querySelector(options.el);
    this.$data = options.data;
    this.proxyData();
    this.compile(this.$el);
  }
  proxyData() {
    for (let key in this.$data) {
      Object.defineProperty(this, key, {
        get() {
          return this.$data[key];
        },
        set(newVal) {
          this.$data[key] = newVal;
          updateView(); // 实际应触发 Watcher 更新  
        }
      });
    }
  }
  compile(node) {
    // 实现模板解析与指令绑定  
  }
}

注意事项

  • 现代框架(如 Vue 3)使用 Proxy 替代 Object.defineProperty,支持深层对象监听。
  • 性能优化需避免频繁 DOM 操作,可通过虚拟 DOM 或批处理更新实现。
  • 实际项目中建议直接使用 Vue 或 React 等成熟框架。

标签: jsmvvm
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 实现页面跳转,这是最常用的方法。 window.location.href = 'https://…

js实现复制

js实现复制

使用document.execCommand方法 在较旧的浏览器中,可以使用document.execCommand('copy')实现复制功能。创建一个临时的textarea或input元素,将需要…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…

js jquery

js jquery

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够…

利用js实现

利用js实现

使用 JavaScript 实现 在 JavaScript 中,可以通过多种方式实现功能,具体取决于需求。以下是几种常见的方法: 方法一:使用原生 JavaScript // 示例代码 funct…

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…