当前位置:首页 > 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合并多次更新:

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

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

js mvvm 实现

标签: jsmvvm
分享给朋友:

相关文章

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

js实现倒计时

js实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callbac…

js实现计算器

js实现计算器

实现基础计算器功能 使用JavaScript创建一个基础计算器需要处理数字输入、运算符逻辑和结果显示。以下是一个简单的实现示例: let currentInput = '0'; let previ…

js实现验证码

js实现验证码

使用Canvas生成图形验证码 在HTML中创建一个Canvas元素用于绘制验证码。通过JavaScript随机生成数字或字母组合,并添加干扰线、噪点等干扰元素增强安全性。 <canvas…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="sli…