当前位置:首页 > VUE

使用vue实现mvvm框架

2026-02-24 17:48:04VUE

Vue 实现 MVVM 框架的核心原理

Vue 的 MVVM(Model-View-ViewModel)实现主要依赖数据绑定和响应式系统。以下是关键实现步骤:

数据劫持(响应式核心)

通过 Object.definePropertyProxy 监听数据变化:

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

依赖收集(发布-订阅模式)

实现 Dep(依赖收集器)和 Watcher(观察者):

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

class Watcher {
  constructor(vm, exp, cb) {
    this.vm = vm;
    this.exp = exp;
    this.cb = cb;
    this.value = this.get();
  }
  get() {
    Dep.target = this;
    const value = this.vm.data[this.exp];
    Dep.target = null;
    return value;
  }
  update() {
    const newVal = this.vm.data[this.exp];
    if (this.value !== newVal) {
      this.value = newVal;
      this.cb.call(this.vm, newVal);
    }
  }
}

模板编译

实现简易模板编译器:

function compile(node, vm) {
  if (node.nodeType === 1) {
    Array.from(node.attributes).forEach(attr => {
      if (attr.name.startsWith('v-')) {
        const exp = attr.value;
        new Watcher(vm, exp, value => {
          node.value = value;
        });
        node.addEventListener('input', e => {
          vm.data[exp] = e.target.value;
        });
      }
    });
  } else if (node.nodeType === 3) {
    const reg = /\{\{(.*)\}\}/;
    const match = node.nodeValue.match(reg);
    if (match) {
      const exp = match[1].trim();
      new Watcher(vm, exp, value => {
        node.nodeValue = value;
      });
    }
  }
  Array.from(node.childNodes).forEach(child => {
    compile(child, vm);
  });
}

整合实现

创建 Vue 类整合上述功能:

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

使用示例

<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>

<script>
new Vue({
  el: document.getElementById('app'),
  data: {
    message: 'Hello MVVM!'
  }
});
</script>

现代改进方案

对于 Vue 3.0+ 版本,推荐使用 Proxy 替代 Object.defineProperty

使用vue实现mvvm框架

function reactive(data) {
  return new Proxy(data, {
    get(target, key) {
      const dep = getDep(target, key);
      dep.depend();
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      const result = Reflect.set(target, key, value);
      const dep = getDep(target, key);
      dep.notify();
      return result;
    }
  });
}

这种实现方式解决了数组监听和嵌套对象的问题,性能更优。

标签: 框架vue
分享给朋友:

相关文章

vue实现全局遮罩层

vue实现全局遮罩层

实现全局遮罩层的方法 在Vue中实现全局遮罩层可以通过多种方式完成,以下是几种常见的实现方法: 使用Vue组件创建遮罩层 创建一个遮罩层组件,通过全局注册或动态挂载的方式实现全局调用。以下是一个简单…

vue实现递归

vue实现递归

Vue 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据(如菜单、评论列表、文件目录等)。以下是具体实现方法: 定义递归组件 通过 name 选项让组件可以递归调用自身:…

实现vue table

实现vue table

Vue 表格实现方法 基础表格实现 使用 Vue 的 v-for 指令可以快速渲染表格数据。在模板中定义表格结构,通过数据绑定动态生成行和列。 <template> <tabl…

vue实现注销

vue实现注销

实现用户注销功能 在Vue应用中实现用户注销功能通常涉及清除用户会话、重置应用状态并跳转到登录页面。以下是具体实现方法: 清除用户认证信息 使用Vuex或Pinia管理用户状态时,需在注销时重置存储…

vue 实现fadeout

vue 实现fadeout

Vue 实现淡出效果 在 Vue 中实现淡出(fade-out)效果可以通过 CSS 过渡或动画结合 Vue 的动态渲染功能完成。以下是几种常见方法: 使用 Vue 过渡(Transition)组件…

vue实现京东

vue实现京东

Vue 实现京东电商网站的关键步骤 项目搭建与基础配置 使用 Vue CLI 或 Vite 初始化项目,安装 Vue Router 管理路由,Vuex/Pinia 管理状态。配置基础 UI 框架如 E…