当前位置:首页 > JavaScript

js mvvm 实现

2026-03-01 03:58:53JavaScript

MVVM 实现原理

MVVM(Model-View-ViewModel)是一种前端架构模式,通过数据绑定实现视图与数据的自动同步。核心在于ViewModel作为中间层,连接View和Model。

核心实现步骤

数据劫持(响应式) 通过Object.definePropertyProxy监听数据变化:

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

模板编译 解析DOM模板中的指令(如v-model)并建立绑定关系:

function compile(el) {
  const nodes = el.querySelectorAll('[v-model]');
  nodes.forEach(node => {
    const key = node.getAttribute('v-model');
    node.addEventListener('input', (e) => {
      viewModel[key] = e.target.value; // 数据变更触发Proxy.set
    });
    node.value = viewModel[key]; // 初始化值
  });
}

依赖收集 通过Dep类和Watcher实现发布-订阅模式:

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

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

完整示例实现

class MiniVue {
  constructor(options) {
    this.$el = document.querySelector(options.el);
    this.$data = options.data();

    this.observe(this.$data);
    this.compile(this.$el);
  }

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

  compile(el) {
    const childNodes = el.childNodes;
    childNodes.forEach(node => {
      if (node.nodeType === 3) { // 文本节点
        const text = node.textContent;
        const reg = /\{\{(.*?)\}\}/;
        if (reg.test(text)) {
          const key = RegExp.$1.trim();
          new Watcher(this.$data, key, val => {
            node.textContent = text.replace(reg, val);
          });
          node.textContent = text.replace(reg, this.$data[key]);
        }
      }
    });
  }
}

关键优化点

虚拟DOM Diff 复杂场景下可引入虚拟DOM提高性能:

function createVNode(tag, props, children) {
  return { tag, props, children };
}

function diff(oldVNode, newVNode) {
  // 实现差异对比算法
}

批量异步更新 使用PromiseMutationObserver合并多次更新:

js mvvm 实现

let pending = false;
function queueUpdate() {
  if (!pending) {
    pending = true;
    Promise.resolve().then(() => {
      updateView();
      pending = false;
    });
  }
}

以上实现展示了MVVM的核心机制,实际框架(如Vue)会包含更多优化和功能扩展。

标签: jsmvvm
分享给朋友:

相关文章

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

jquery.js

jquery.js

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

js钟表实现

js钟表实现

实现JavaScript钟表的基本方法 创建一个简单的JavaScript钟表可以通过以下步骤完成,涵盖数字和模拟两种形式。 数字钟表实现 HTML结构只需一个显示时间的容器: <div i…

js 实现滚动

js 实现滚动

实现滚动的方法 使用 window.scrollTo() window.scrollTo() 方法可以滚动到文档中的特定位置。可以指定 x 和 y 坐标,或者使用平滑滚动的选项。 // 滚动到指定位…

js 实现按钮点击

js 实现按钮点击

实现按钮点击的 JavaScript 方法 HTML 按钮元素 在 HTML 中创建一个按钮,可以通过 <button> 或 <input> 标签实现: <button…

js实现截图

js实现截图

使用HTML2Canvas库实现截图 HTML2Canvas是一个流行的JavaScript库,可以将网页元素或整个页面转换为Canvas图像。安装方式: npm install html2canv…