当前位置:首页 > JavaScript

js mvvm实现

2026-01-31 22:24:41JavaScript

MVVM 模式简介

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

核心实现步骤

数据劫持(响应式原理)

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

// Proxy 实现  
const reactive = (obj) => {
  return new Proxy(obj, {
    get(target, key) {
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      Reflect.set(target, key, value);
      console.log(`数据更新: ${key} = ${value}`);
      // 触发视图更新  
      return true;
    }
  });
};

模板编译

解析 DOM 模板,替换插值表达式(如 {{data}})并建立依赖关系:

function compile(el, vm) {
  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 = vm.data[key];
        // 监听数据变化并更新视图  
        new Watcher(vm, key, (val) => {
          node.textContent = val;
        });
      }
    }
  });
}

依赖收集(发布-订阅)

通过 DepWatcher 实现数据变化的订阅与通知:

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; // 标记当前 Watcher  
    this.value = vm.data[key]; // 触发 getter 收集依赖  
    Dep.target = null;
  }
  update() {
    this.value = this.vm.data[this.key];
    this.cb(this.value);
  }
}

整合 ViewModel

将数据劫持、模板编译和依赖收集结合:

class MVVM {
  constructor(options) {
    this.data = reactive(options.data); // 响应式数据  
    this.el = document.querySelector(options.el);
    compile(this.el, this); // 编译模板  
  }
}

使用示例

<div id="app">{{message}}</div>
<script>
  const vm = new MVVM({
    el: '#app',
    data: { message: 'Hello MVVM!' }
  });
  setTimeout(() => {
    vm.data.message = 'Data changed!'; // 触发视图更新  
  }, 1000);
</script>

注意事项

  • 现代框架(如 Vue 3)使用 Proxy 替代 Object.defineProperty,支持深层对象监听。
  • 虚拟 DOM 可优化直接操作 DOM 的性能问题。
  • 双向绑定可通过 v-model 等指令扩展实现。

js mvvm实现

标签: jsmvvm
分享给朋友:

相关文章

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 使用JavaScript实现拖拽功能需要监听鼠标事件,包括mousedown、mousemove和mouseup。以下是实现的基本逻辑: const draggableElem…

js实现验证码

js实现验证码

实现验证码的JavaScript方法 生成随机验证码 使用Math.random()生成随机字符串,结合数字和字母: function generateCaptcha() { const cha…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现文件下载

js实现文件下载

使用 a 标签下载文件 通过动态创建 a 标签并设置 download 属性实现文件下载。适用于已知文件 URL 或 Blob 数据的情况。 function downloadFile(url, f…

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('imag…