当前位置:首页 > VUE

vue原理与实现

2026-01-16 18:51:04VUE

Vue 的核心原理

Vue 是一个渐进式 JavaScript 框架,其核心原理包括响应式系统、虚拟 DOM、模板编译和组件化设计。这些机制共同构成了 Vue 的高效开发模式。

响应式系统通过 Object.definePropertyProxy 实现数据劫持,当数据变化时自动触发视图更新。Vue 3 使用 Proxy 替代了 Vue 2 的 Object.defineProperty,解决了数组和对象属性监听不全的问题。

虚拟 DOM 是一个轻量级的 JavaScript 对象,描述真实 DOM 结构。通过对比新旧虚拟 DOM 的差异,最小化 DOM 操作,提升性能。

模板编译将模板字符串转换为渲染函数。Vue 2 使用正则表达式解析模板,Vue 3 改用基于有限状态机的解析器,效率更高。

vue原理与实现

实现简易 Vue 响应式系统

以下是一个基于 Proxy 的简易响应式实现:

function reactive(target) {
  const handler = {
    get(target, key, receiver) {
      track(target, key);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      const oldValue = target[key];
      const result = Reflect.set(target, key, value, receiver);
      if (oldValue !== value) {
        trigger(target, key);
      }
      return result;
    }
  };
  return new Proxy(target, handler);
}

const targetMap = new WeakMap();
function track(target, key) {
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()));
  }
  let dep = depsMap.get(key);
  if (!dep) {
    depsMap.set(key, (dep = new Set()));
  }
  dep.add(effect);
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  const dep = depsMap.get(key);
  if (dep) {
    dep.forEach(effect => effect());
  }
}

虚拟 DOM 的简单实现

虚拟 DOM 的核心是 h 函数创建虚拟节点和 patch 函数对比更新:

vue原理与实现

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

function patch(oldNode, newNode) {
  if (oldNode.tag === newNode.tag) {
    const el = (newNode.el = oldNode.el);
    // 更新属性
    const oldProps = oldNode.props || {};
    const newProps = newNode.props || {};
    for (const key in newProps) {
      if (newProps[key] !== oldProps[key]) {
        el.setAttribute(key, newProps[key]);
      }
    }
    for (const key in oldProps) {
      if (!(key in newProps)) {
        el.removeAttribute(key);
      }
    }
    // 更新子节点
    const oldChildren = oldNode.children || [];
    const newChildren = newNode.children || [];
    if (typeof newChildren === 'string') {
      if (typeof oldChildren === 'string') {
        if (newChildren !== oldChildren) {
          el.textContent = newChildren;
        }
      } else {
        el.textContent = newChildren;
      }
    } else {
      if (typeof oldChildren === 'string') {
        el.innerHTML = '';
        newChildren.forEach(child => {
          const childEl = createElement(child);
          el.appendChild(childEl);
        });
      } else {
        updateChildren(el, oldChildren, newChildren);
      }
    }
  } else {
    // 替换整个节点
    const parent = oldNode.el.parentNode;
    parent.removeChild(oldNode.el);
    const newEl = createElement(newNode);
    parent.appendChild(newEl);
  }
}

组件系统实现原理

Vue 组件本质上是带有预定义选项的可复用 Vue 实例。组件的核心实现包括:

  1. 组件注册:通过 Vue.component 全局注册或 components 选项局部注册
  2. 组件实例化:创建组件构造函数,继承自 Vue 基类
  3. 生命周期管理:从创建到销毁的各个阶段钩子函数
function createComponent(Ctor, data, context, children) {
  const propsData = extractProps(data, Ctor.props);
  const listeners = data.on || {};
  const vnode = new VNode(
    `vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
    data, undefined, undefined, undefined, context,
    { Ctor, propsData, listeners, children }
  );
  return vnode;
}

模板编译过程

Vue 模板编译分为三个阶段:

  1. 解析:将模板字符串转换为 AST(抽象语法树)
  2. 优化:标记静态节点,减少 diff 过程中的比较
  3. 代码生成:将 AST 转换为可执行的渲染函数
function compile(template) {
  const ast = parse(template);
  optimize(ast);
  const code = generate(ast);
  return new Function(`with(this){return ${code}}`);
}

function parse(template) {
  // 实现模板解析逻辑
  // 返回 AST
}

function optimize(ast) {
  // 标记静态节点
}

function generate(ast) {
  // 生成渲染函数代码字符串
}

响应式系统的依赖收集

依赖收集是响应式系统的核心,通过 DepWatcher 实现:

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  }
  notify() {
    this.subscribers.forEach(effect => effect());
  }
}

let activeEffect = null;
function watchEffect(effect) {
  activeEffect = effect;
  effect();
  activeEffect = null;
}

以上实现展示了 Vue 核心功能的简化版本,实际 Vue 源码更加复杂,包含更多边界情况处理和性能优化。理解这些基本原理有助于更好地使用 Vue 和解决开发中的问题。

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

相关文章

vue实现滚动中断

vue实现滚动中断

Vue 实现滚动中断的方法 在 Vue 中实现滚动中断通常涉及监听滚动事件,并在特定条件下阻止默认行为或停止滚动。以下是几种常见方法: 监听滚动事件并阻止默认行为 通过 @scroll 或 @wh…

vue如何实现冒泡

vue如何实现冒泡

Vue 实现冒泡排序 在 Vue 中实现冒泡排序,可以通过数据绑定和响应式特性动态展示排序过程。以下是一个完整的实现示例,包含代码和详细说明。 数据准备 在 Vue 的 data 中定义一个数组作…

vue实现文字播放栏

vue实现文字播放栏

Vue 实现文字播放栏(跑马灯效果) 方法一:使用 CSS 动画 + Vue 数据绑定 通过 CSS 的 @keyframes 实现动画效果,结合 Vue 的动态数据绑定控制内容。 <tem…

vue实现按卡片轮播

vue实现按卡片轮播

实现卡片轮播的基本思路 在Vue中实现卡片轮播可以通过结合v-for指令和动态样式绑定完成。核心是维护一个当前显示卡片的索引,通过CSS过渡效果实现平滑切换。 基础实现步骤 模板部分 使用v-fo…

vue 实现在线预览

vue 实现在线预览

Vue 实现在线预览的常见方法 使用 iframe 嵌入 通过 iframe 标签可以嵌入多种类型的文件,如 PDF、图片、网页等。需要确保文件地址可访问。 <template>…

vue实现继承语法糖

vue实现继承语法糖

在Vue中实现继承可以通过多种方式模拟类继承的效果,以下是常见的几种方法: 使用mixins实现逻辑复用 通过Vue的mixins机制共享组件选项,达到类似继承的效果: const BaseC…