当前位置:首页 > JavaScript

js 实现vue

2026-02-02 02:35:39JavaScript

Vue.js 的基本实现

在 JavaScript 中实现 Vue.js 的核心功能,主要包括数据响应式、模板编译和虚拟 DOM。以下是一个简化的实现示例。

数据响应式

使用 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());
  }
}

观察者模式

实现一个简单的观察者(Watcher),用于更新视图:

class Watcher {
  constructor(vm, key, cb) {
    this.vm = vm;
    this.key = key;
    this.cb = cb;
    Dep.target = this;
    this.vm[this.key]; // 触发 getter
    Dep.target = null;
  }
  update() {
    this.cb.call(this.vm, this.vm[this.key]);
  }
}

模板编译

实现一个简单的模板编译器,将模板转换为渲染函数:

function compile(template) {
  const el = document.createElement('div');
  el.innerHTML = template;
  const fragment = document.createDocumentFragment();
  while (el.firstChild) {
    fragment.appendChild(el.firstChild);
  }
  return function render() {
    return fragment.cloneNode(true);
  };
}

虚拟 DOM

实现一个简化的虚拟 DOM 和 diff 算法:

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

function patch(oldNode, newNode) {
  if (oldNode.tag !== newNode.tag) {
    oldNode.el.parentNode.replaceChild(createEl(newNode), oldNode.el);
  } else {
    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 => {
          el.appendChild(createEl(child));
        });
      } else {
        updateChildren(el, oldChildren, newChildren);
      }
    }
  }
}

function updateChildren(parent, oldChildren, newChildren) {
  const len = Math.max(oldChildren.length, newChildren.length);
  for (let i = 0; i < len; i++) {
    patch(oldChildren[i], newChildren[i]);
  }
}

function createEl(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]);
  }
  if (Array.isArray(vnode.children)) {
    vnode.children.forEach(child => {
      el.appendChild(createEl(child));
    });
  } else {
    el.textContent = vnode.children;
  }
  return el;
}

整合实现

将以上部分整合为一个简单的 Vue 类:

js 实现vue

class Vue {
  constructor(options) {
    this.$options = options;
    this._data = options.data();
    this.observe(this._data);
    this.compile(options.template);
  }

  observe(data) {
    for (const key in data) {
      defineReactive(this, key, data[key]);
    }
  }

  compile(template) {
    const render = compile(template);
    const vnode = render();
    new Watcher(this, '_data', () => {
      const newVnode = render();
      patch(vnode, newVnode);
    });
  }
}

使用示例

const vm = new Vue({
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  template: '<div>{{ message }}</div>'
});

注意事项

  • 以上实现是一个简化的版本,实际 Vue.js 的实现更为复杂。
  • 现代 Vue 3 使用 Proxy 替代 Object.defineProperty 实现响应式。
  • 虚拟 DOM 和 diff 算法在实际应用中需要更高效的实现。

标签: jsvue
分享给朋友:

相关文章

vue 实现全屏

vue 实现全屏

Vue 实现全屏功能 在 Vue 中实现全屏功能可以通过浏览器提供的 Fullscreen API 完成。以下是一个完整的实现方案: 安装依赖(可选) 如果需要跨浏览器兼容性更好,可以安装…

vue 实现modal

vue 实现modal

Vue 实现 Modal 的方法 使用 Vue 原生组件 通过 Vue 的组件系统可以轻松实现 Modal。创建一个可复用的 Modal 组件,通过 props 控制显示与隐藏。 <templ…

vue cli 实现

vue cli 实现

Vue CLI 实现步骤 安装 Vue CLI 确保 Node.js 版本在 8.9 或以上。通过 npm 全局安装 Vue CLI: npm install -g @vue/cli 创建新项目 使…

vue实现github

vue实现github

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

vue实现mvvm

vue实现mvvm

Vue 实现 MVVM 模式 MVVM(Model-View-ViewModel)是一种前端架构模式,Vue 是其典型实现之一。MVVM 的核心是通过数据绑定和响应式系统实现视图与数据的自动同步。…

vue实现CRUD

vue实现CRUD

Vue 实现 CRUD 操作 Vue 提供了响应式数据绑定和组件化开发能力,结合后端 API 可以轻松实现 CRUD(增删改查)功能。以下是基于 Vue 3 和 Axios 的完整实现方案。 安装依…