当前位置:首页 > 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 的调用方式:

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 实现登录验证的方法 使用表单验证库 VeeValidate 安装 VeeValidate 库,可以快速实现表单验证功能。VeeValidate 提供了丰富的验证规则和错误提示功能。 npm…

vue前端实现登录

vue前端实现登录

实现登录功能的基本流程 使用Vue实现登录功能需要结合前端框架和后端API交互。以下是一个典型的实现方案: 安装必要依赖 确保项目已安装axios用于HTTP请求: npm install a…

vue实现文章锚点定位

vue实现文章锚点定位

实现文章锚点定位的方法 在Vue中实现文章锚点定位可以通过多种方式完成,以下是几种常见的方法: 使用原生HTML锚点 通过HTML的id属性和<a>标签的href属性实现锚点跳转。在V…

vue实现a4打印模板

vue实现a4打印模板

使用Vue实现A4打印模板 在Vue中实现A4打印模板需要结合CSS的打印样式和Vue的模板渲染能力。以下是具体实现方法: 设置A4纸张尺寸 在CSS中定义A4纸张的标准尺寸(210mm × 297…

vue实现单点

vue实现单点

Vue 实现单点登录(SSO)方案 单点登录(SSO)允许用户在多个相关但独立的系统中使用同一组凭证登录。以下是基于 Vue 的实现方案: 基于 OAuth2/OpenID Connect 的实现…

vue优秀实现

vue优秀实现

Vue.js 优秀实现方法 响应式数据管理 使用 Vue 的 ref 和 reactive 处理基础类型和对象类型数据,结合 computed 计算属性优化渲染性能。对于复杂状态,推荐 Pinia 替…