当前位置:首页 > VUE

原生实现vue功能

2026-01-14 02:48:48VUE

原生 JavaScript 实现 Vue 核心功能

使用原生 JavaScript 模拟 Vue 的核心功能(如数据绑定、虚拟 DOM、响应式更新等),可以通过以下方式实现:

数据响应式系统

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

原生实现vue功能

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(); // 触发更新
      }
    });
  });
}

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

模板编译与虚拟 DOM

实现简单的模板解析和虚拟 DOM 生成:

原生实现vue功能

function compile(template, data) {
  const el = document.querySelector(template);
  const fragment = document.createDocumentFragment();
  let child;
  while (child = el.firstChild) {
    fragment.appendChild(child);
  }
  replace(fragment, data);
  el.appendChild(fragment);
}

function replace(node, data) {
  const reg = /\{\{(.*?)\}\}/g;
  if (node.nodeType === 3) { // 文本节点
    const text = node.textContent;
    if (reg.test(text)) {
      const key = RegExp.$1.trim();
      node.textContent = text.replace(reg, data[key]);
      new Watcher(data, key, (val) => {
        node.textContent = text.replace(reg, val);
      });
    }
    return;
  }
  if (node.nodeType === 1) { // 元素节点
    const attrs = node.attributes;
    for (let i = 0; i < attrs.length; i++) {
      const name = attrs[i].name;
      if (name.startsWith('v-')) {
        const exp = attrs[i].value;
        node.value = data[exp];
        new Watcher(data, exp, (val) => {
          node.value = val;
        });
        node.addEventListener('input', (e) => {
          data[exp] = e.target.value;
        });
      }
    }
  }
  Array.from(node.childNodes).forEach(child => replace(child, data));
}

观察者与依赖管理

实现 Watcher 类连接响应式数据和视图:

class Watcher {
  constructor(data, key, cb) {
    this.data = data;
    this.key = key;
    this.cb = cb;
    Dep.target = this;
    this.value = data[key]; // 触发getter收集依赖
    Dep.target = null;
  }
  update() {
    const newVal = this.data[this.key];
    if (newVal !== this.value) {
      this.value = newVal;
      this.cb(newVal);
    }
  }
}

简易调用示例

整合以上功能实现类似 Vue 的调用方式:

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

// 使用示例
new MiniVue({
  el: '#app',
  data() {
    return { message: 'Hello MiniVue', count: 0 };
  }
});

注意事项

  1. 此实现仅为演示核心原理,实际 Vue 源码包含更多优化(如异步更新、Diff 算法等)。
  2. ProxyObject.defineProperty 能更好地处理数组和嵌套对象。
  3. 现代前端框架通常使用虚拟 DOM 和差异化更新算法提升性能。
  4. 完整实现还需考虑组件系统、生命周期等复杂功能。

标签: 功能vue
分享给朋友:

相关文章

vue实现预约页面

vue实现预约页面

Vue 预约页面实现步骤 准备工作 安装Vue CLI创建项目,确保已配置好开发环境。使用vue create appointment-page初始化项目,选择默认配置或手动配置。 页面结构设计 在…

简单实现vue

简单实现vue

Vue 的基本实现 创建一个简单的 Vue 应用需要引入 Vue 库,并编写基本的模板和数据绑定逻辑。 <!DOCTYPE html> <html lang="en"> &l…

vue el 实现

vue el 实现

Vue 中使用 Element UI (el) 的实现方法 Element UI 是一个基于 Vue 的组件库,提供丰富的 UI 组件,常用于快速构建企业级中后台产品。以下介绍 Vue 项目中集成和使…

vue实现签章

vue实现签章

Vue 实现签章功能 签章功能通常包括手写签名、电子印章等。以下是基于 Vue 的实现方法: 使用 canvas 实现手写签名 安装依赖(如需要): npm install signature_p…

vue实现树

vue实现树

Vue 实现树形结构的方法 使用递归组件实现树形结构 递归组件是Vue中实现树形结构的常见方式。通过组件调用自身,可以轻松构建多层嵌套的树形数据。 <template> <ul…

vue拖动实现

vue拖动实现

实现 Vue 拖动功能的方法 使用 HTML5 拖放 API 在 Vue 中可以利用 HTML5 的原生拖放 API 实现拖动功能。通过 draggable 属性标记可拖动元素,结合 @dragsta…