当前位置:首页 > VUE

模拟vue实现原理

2026-01-19 05:30:32VUE

Vue 实现原理的核心模块

Vue 的核心实现原理主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下是模拟 Vue 这些核心功能的简化实现方法。

响应式系统

Vue 使用 Object.definePropertyProxy 实现数据劫持,监听数据变化并触发更新。

基于 Object.defineProperty 的简化实现:

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 依赖收集器

  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) {
        dep.addSub(Dep.target); // 收集依赖
      }
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 通知更新
    },
  });
}

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

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

虚拟 DOM 与 Diff 算法

虚拟 DOM 是一个轻量级的 JavaScript 对象,用于描述真实 DOM 结构。Diff 算法通过对比新旧虚拟 DOM 的差异,最小化 DOM 操作。

虚拟 DOM 的简化实现:

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

function render(vnode) {
  if (typeof vnode === 'string') return document.createTextNode(vnode);

  const el = document.createElement(vnode.tag);
  for (const key in vnode.props) {
    el.setAttribute(key, vnode.props[key]);
  }
  vnode.children.forEach(child => {
    el.appendChild(render(child));
  });
  return el;
}

function patch(oldNode, newNode) {
  if (oldNode.tag !== newNode.tag) {
    return render(newNode); // 直接替换
  }

  const el = oldNode.el;
  for (const key in newNode.props) {
    if (newNode.props[key] !== oldNode.props[key]) {
      el.setAttribute(key, newNode.props[key]);
    }
  }

  const oldChildren = oldNode.children;
  const newChildren = newNode.children;
  for (let i = 0; i < Math.max(oldChildren.length, newChildren.length); i++) {
    if (!oldChildren[i]) {
      el.appendChild(render(newChildren[i]));
    } else if (!newChildren[i]) {
      el.removeChild(oldChildren[i].el);
    } else {
      patch(oldChildren[i], newChildren[i]);
    }
  }
  return el;
}

模板编译

Vue 将模板编译为渲染函数,生成虚拟 DOM。以下是一个极简的模板编译示例:

function compile(template) {
  const ast = parse(template); // 解析为 AST(抽象语法树)
  const code = generate(ast); // 生成渲染函数代码
  return new Function(`with(this) { return ${code} }`);
}

// 示例:简单插值表达式
function parse(template) {
  return {
    type: 'element',
    tag: 'div',
    children: [{
      type: 'text',
      content: `{{ message }}`
    }]
  };
}

function generate(ast) {
  return `createElement("${ast.tag}", {}, [this.message])`;
}

组件化机制

Vue 组件是带有预定义选项的可复用实例。以下是组件注册和渲染的简化逻辑:

class Vue {
  constructor(options) {
    this.$options = options;
    this._data = options.data();
    this._initReactive();
    this.$mount(options.el);
  }

  _initReactive() {
    Object.keys(this._data).forEach(key => {
      defineReactive(this, key, this._data[key]);
    });
  }

  $mount(el) {
    this.$el = document.querySelector(el);
    const updateComponent = () => {
      const vnode = this.$options.render.call(this);
      patch(this.$el, vnode);
    };
    new Watcher(this, updateComponent);
  }
}

// 使用示例
const app = new Vue({
  el: '#app',
  data: () => ({ message: 'Hello Vue' }),
  render() {
    return createElement('div', {}, [this.message]);
  }
});

总结

  1. 响应式系统:通过数据劫持和依赖收集实现数据驱动视图。
  2. 虚拟 DOM:用 JavaScript 对象描述 DOM 结构,配合 Diff 算法高效更新视图。
  3. 模板编译:将模板转换为渲染函数,生成虚拟 DOM。
  4. 组件化:将 UI 拆分为独立可复用的组件实例。

以上是 Vue 核心原理的简化实现,实际 Vue 源码还包含更多优化和边界处理。

模拟vue实现原理

标签: 原理vue
分享给朋友:

相关文章

vue实现裁剪头像

vue实现裁剪头像

Vue 实现头像裁剪功能 实现头像裁剪功能通常需要结合第三方库如 cropperjs 或 vue-cropper。以下是两种常见实现方式: 使用 vue-cropper 库 安装依赖: n…

vue实现本地数据存储

vue实现本地数据存储

使用 localStorage 或 sessionStorage Vue 中可以直接调用浏览器提供的 localStorage 或 sessionStorage API 进行数据存储。localSto…

vue实现点击旋转轮盘

vue实现点击旋转轮盘

实现点击旋转轮盘效果 在Vue中实现点击旋转轮盘效果,可以通过CSS动画和Vue的数据绑定结合完成。以下是一个完整的实现方案: 准备工作 需要安装Vue.js环境,可以通过CDN引入或使用Vue…

vue实现倒计时抢券

vue实现倒计时抢券

Vue 实现倒计时抢券功能 核心逻辑 倒计时抢券功能需要结合时间计算、状态管理和界面交互。通过 Vue 的响应式特性和生命周期钩子,可以高效实现这一需求。 实现步骤 1. 数据准备 在 Vue 组…

vue实现input

vue实现input

Vue 实现 Input 输入框的方法 基本双向绑定 使用 v-model 指令实现双向数据绑定,适用于大多数表单场景: <template> <input v-model=…

vue实现erp

vue实现erp

Vue实现ERP系统的关键步骤 技术选型与架构设计 采用Vue 3 + TypeScript构建前端,搭配Pinia状态管理,Element Plus或Ant Design Vue作为UI框架。后端可…