当前位置:首页 > VUE

原生实现vue功能

2026-01-14 02:48:48VUE

原生 JavaScript 实现 Vue 核心功能

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

数据响应式系统

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

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

模板编译与虚拟 DOM

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

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 的调用方式:

原生实现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.js设计与实现》是一本深入探讨Vue.js框架内部原理和设计思想的书籍,适合希望深入理解Vue.js的开发者。以下是关于这本书的详细信息: 书籍内容 《Vue.js设…

vue实现route

vue实现route

Vue 路由实现方法 Vue 中实现路由通常使用 vue-router 库,这是 Vue 官方推荐的路由管理器。以下是具体实现步骤: 安装 vue-router 通过 npm 或 yarn 安装…

vue实现slot

vue实现slot

Vue 中的 Slot 实现方法 Vue 的 slot 是一种内容分发机制,允许父组件向子组件插入内容。以下是几种常见的 Slot 实现方式: 默认 Slot 子组件通过 <slot>…

vue实现多选

vue实现多选

Vue 实现多选功能 在 Vue 中实现多选功能可以通过多种方式完成,以下是常见的几种方法: 使用 v-model 绑定数组 通过 v-model 绑定到一个数组,可以实现多选功能。适用于复选框组(…

vue实现github

vue实现github

Vue 实现 GitHub 相关功能 创建 GitHub API 请求 在 Vue 项目中,可以使用 axios 或 fetch 与 GitHub API 进行交互。需要在 GitHub 上创建个人访…

vue实现banner

vue实现banner

Vue实现Banner轮播 使用Vue实现Banner轮播可以通过第三方库如swiper或vue-awesome-swiper,也可以手动实现基础轮播效果。以下是两种常见方法: 使用vue-…