当前位置:首页 > 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 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

js实现轮播图

js实现轮播图

轮播图实现方法 基础HTML结构 <div class="slider"> <div class="slides"> <img src="image1.jpg…

js画图实现

js画图实现

使用Canvas API绘制图形 Canvas是HTML5提供的绘图API,通过JavaScript操作Canvas元素可以绘制各种图形。以下是一个简单的示例: <canvas id="myC…

js图片上传实现

js图片上传实现

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

js实现删除

js实现删除

使用 splice 方法删除数组元素 splice 方法可以删除数组中的元素,并返回被删除的元素。它接受两个参数:起始索引和要删除的元素数量。 const array = [1, 2, 3, 4…

js验证码实现

js验证码实现

验证码的基本原理 验证码(CAPTCHA)用于区分人类用户和自动化程序。常见类型包括图形验证码、滑动验证码、短信验证码等。JavaScript 可用于前端验证码的生成和验证逻辑。 图形验证码实现 使…