当前位置:首页 > JavaScript

js 实现mvvm

2026-03-15 09:12:58JavaScript

MVVM 模式简介

MVVM(Model-View-ViewModel)是一种前端架构模式,通过数据绑定实现视图(View)与数据模型(Model)的分离。ViewModel 作为中间层,负责处理业务逻辑和数据绑定,使开发者无需直接操作 DOM。

核心实现步骤

数据劫持(响应式数据)

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

js 实现mvvm

function observe(data) {
  if (!data || typeof data !== 'object') return;
  return new Proxy(data, {
    get(target, key) {
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      notifyUpdate(); // 触发视图更新
      return true;
    }
  });
}

模板编译

解析 HTML 模板中的指令(如 v-model{{}}),将数据绑定到视图。

function compile(el, vm) {
  const fragment = document.createDocumentFragment();
  let child;
  while (child = el.firstChild) {
    fragment.appendChild(child);
  }
  // 替换模板中的插值表达式
  const reg = /\{\{(.*?)\}\}/g;
  fragment.textContent = fragment.textContent.replace(reg, (match, key) => {
    return vm.data[key.trim()];
  });
  el.appendChild(fragment);
}

依赖收集与更新

实现一个简单的依赖管理器(Dep)和观察者(Watcher),在数据变化时通知视图更新。

js 实现mvvm

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

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

双向绑定实现

通过 v-model 指令实现表单元素与数据的双向绑定。

function bindInput(el, vm, key) {
  el.addEventListener('input', (e) => {
    vm.data[key] = e.target.value;
  });
  new Watcher(vm, key, (value) => {
    el.value = value;
  });
}

完整示例

以下是一个极简的 MVVM 实现框架:

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

// 使用示例
const vm = new MVVM({
  el: '#app',
  data: () => ({ message: 'Hello MVVM!' })
});

注意事项

  • 现代框架(如 Vue 3)使用 Proxy 替代 Object.defineProperty,性能更好且支持数组监听。
  • 实际项目中需处理复杂指令(如 v-for)、虚拟 DOM 等优化。
  • 可结合 Virtual DOM 库(如 Snabbdom)实现高效视图更新。

标签: jsmvvm
分享给朋友:

相关文章

js 进度条的实现

js 进度条的实现

使用 HTML 和 CSS 创建基础进度条 HTML 结构可以简单使用一个 div 元素作为容器,内部嵌套另一个 div 表示进度: <div class="progress-containe…

vue实现mvvm

vue实现mvvm

Vue 实现 MVVM 的原理 Vue 的 MVVM(Model-View-ViewModel)实现主要依赖数据绑定和响应式系统。ViewModel 是 Vue 实例,负责连接 Model 和 Vie…

vue实现js休眠

vue实现js休眠

实现 JavaScript 休眠的方法 在 Vue 中实现 JavaScript 休眠(延迟执行)可以通过以下方式实现。由于 JavaScript 本身没有内置的 sleep 函数,通常使用 Prom…

js节流实现

js节流实现

节流的概念 节流(Throttle)是一种限制函数执行频率的技术,确保函数在一定时间间隔内只执行一次。常用于滚动事件、窗口调整等高频触发的场景。 基础实现方法 使用时间戳判断是否执行函数: fun…

js实现滚动

js实现滚动

实现滚动效果的方法 在JavaScript中实现滚动效果可以通过多种方式完成,以下是一些常见的方法: 使用window.scrollTo() window.scrollTo()方法可以将页面滚动到指…

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…