当前位置:首页 > VUE

从0实现vue

2026-03-08 07:04:04VUE

实现简易 Vue 的核心模块

数据响应式系统
通过 Object.definePropertyProxy 监听数据变化。以下为基于 Object.defineProperty 的简化实现:

function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    get() {
      Dep.target && dep.addSub(Dep.target);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify();
    }
  });
}

依赖收集与发布
实现 Dep(依赖管理器)和 Watcher(观察者):

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

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

模板编译

解析 DOM 模板
将模板中的 {{}} 和指令转换为数据绑定:

从0实现vue

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

  function replace(frag) {
    Array.from(frag.childNodes).forEach(node => {
      const txt = node.textContent;
      const reg = /\{\{(.*?)\}\}/g;
      if (node.nodeType === 3 && reg.test(txt)) {
        const key = RegExp.$1.trim();
        new Watcher(vm, key, newVal => {
          node.textContent = txt.replace(reg, newVal);
        });
        node.textContent = txt.replace(reg, vm[key]);
      }
      if (node.childNodes) replace(node);
    });
  }
  replace(fragment);
  el.appendChild(fragment);
}

初始化 Vue 实例

整合核心模块创建构造函数:

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

  observe(data) {
    Object.keys(data).forEach(key => {
      defineReactive(data, key, data[key]);
      Object.defineProperty(this, key, {
        get() { return data[key]; },
        set(newVal) { data[key] = newVal; }
      });
    });
  }
}

示例用法

<div id="app">{{ message }}</div>
<script>
  const vm = new Vue({
    el: '#app',
    data: { message: 'Hello Vue!' }
  });
  setTimeout(() => {
    vm.message = 'Updated!'; // 视图自动更新
  }, 1000);
</script>

扩展方向

  1. 虚拟 DOM
    实现 patch 函数对比新旧 VNode,提升渲染性能。

    从0实现vue

  2. 指令系统
    支持 v-modelv-for 等指令,例如通过扩展 compile 函数解析指令。

  3. 生命周期钩子
    在特定阶段触发 createdmounted 等回调函数。

  4. 组件化
    通过 Vue.component 注册组件,支持嵌套和 props 通信。

该实现省略了错误处理和边缘情况,实际 Vue 源码包含更复杂的优化和兼容性处理。

标签: vue
分享给朋友:

相关文章

vue 页签实现

vue 页签实现

Vue 页签实现方法 在 Vue 中实现页签功能通常涉及动态组件、路由或状态管理。以下是几种常见的实现方式: 使用动态组件 通过 Vue 的 <component> 动态组件结合 v-f…

vue筛选实现

vue筛选实现

Vue 筛选实现方法 使用计算属性实现筛选 计算属性是 Vue 中实现数据筛选的常用方式。通过定义一个计算属性,可以根据输入的条件动态过滤数据。 <template> <div…

vue实现路由

vue实现路由

Vue 路由的实现方法 Vue 路由可以通过 Vue Router 库来实现,Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue Router 通…

vue 实现筛选

vue 实现筛选

实现筛选功能的基本方法 在Vue中实现筛选功能通常涉及以下几个核心步骤: 数据绑定与筛选逻辑 使用v-model绑定筛选条件到Vue实例的数据属性,结合计算属性实现动态筛选: data() {…

vue实现datalist

vue实现datalist

使用 Vue 实现 HTML5 的 datalist 功能 HTML5 的 <datalist> 元素提供了一种自动完成输入框的功能,允许用户在输入时从预定义的选项列表中选择。以下是几种在…

vue实现验证

vue实现验证

Vue 表单验证实现方法 在Vue中实现表单验证可以通过多种方式完成,以下是常见的几种方法: 使用Vuelidate库 Vuelidate是一个轻量级的Vue表单验证库,安装后可以通过简单的配置实现…