当前位置:首页 > JavaScript

js 实现vue

2026-04-06 19:45:19JavaScript

实现 Vue 的基本功能

使用 JavaScript 实现一个简化版的 Vue,需要核心功能包括数据响应式、模板编译和虚拟 DOM 更新。以下是一个基础实现框架:

class Vue {
  constructor(options) {
    this.$options = options;
    this.$data = options.data();
    this.$el = document.querySelector(options.el);

    this.observe(this.$data);
    this.compile(this.$el);
  }

  observe(data) {
    Object.keys(data).forEach(key => {
      let value = data[key];
      const dep = new Dep();

      Object.defineProperty(data, key, {
        get() {
          Dep.target && dep.addSub(Dep.target);
          return value;
        },
        set(newVal) {
          if (newVal !== value) {
            value = newVal;
            dep.notify();
          }
        }
      });
    });
  }

  compile(node) {
    Array.from(node.childNodes).forEach(child => {
      if (child.nodeType === 3) {
        this.compileText(child);
      } else if (child.nodeType === 1) {
        this.compileElement(child);
        if (child.childNodes.length) {
          this.compile(child);
        }
      }
    });
  }

  compileText(node) {
    const reg = /\{\{(.*?)\}\}/g;
    const text = node.textContent;
    if (reg.test(text)) {
      const key = RegExp.$1.trim();
      node.textContent = this.$data[key];
      new Watcher(this.$data, key, (val) => {
        node.textContent = val;
      });
    }
  }

  compileElement(node) {
    Array.from(node.attributes).forEach(attr => {
      if (attr.name.startsWith('v-')) {
        const dir = attr.name.substring(2);
        const exp = attr.value;
        if (dir === 'model') {
          node.value = this.$data[exp];
          node.addEventListener('input', (e) => {
            this.$data[exp] = e.target.value;
          });
          new Watcher(this.$data, exp, (val) => {
            node.value = val;
          });
        }
      }
    });
  }
}

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

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

  update() {
    this.value = this.data[this.key];
    this.cb(this.value);
  }
}

核心实现原理

数据响应式通过 Object.defineProperty 实现,为每个数据属性创建依赖收集器(Dep)。当数据被访问时收集依赖(Watcher),数据变化时通知所有依赖更新。

模板编译通过遍历 DOM 树实现,解析双花括号文本节点和 v-model 指令节点,为每个动态绑定创建对应的 Watcher 实例。

js 实现vue

使用示例

<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>

<script>
  const app = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue!'
      };
    }
  });
</script>

功能扩展方向

  1. 实现计算属性(computed)
  2. 添加方法(methods)支持
  3. 实现生命周期钩子
  4. 支持组件系统
  5. 实现虚拟 DOM 和 diff 算法

这个实现展示了 Vue 最核心的响应式原理和模板编译机制,实际 Vue 源码更加复杂和完善,包含更多优化和功能特性。

标签: jsvue
分享给朋友:

相关文章

vue实现popup

vue实现popup

Vue 实现 Popup 弹窗 使用 Vue 原生组件 创建一个基本的 Vue 组件作为弹窗,通过 v-if 或 v-show 控制显示隐藏。 <template> <div&…

vue 实现脚本

vue 实现脚本

Vue 实现脚本的方法 Vue.js 提供了多种方式来实现脚本功能,包括组件内脚本、混入(Mixins)、插件(Plugins)以及自定义指令等。以下是常见的实现方式: 组件内脚本 在 Vue 单文…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI 提…

vue实现login

vue实现login

Vue 实现登录功能 在 Vue 中实现登录功能通常需要以下几个步骤: 创建登录表单组件 在 Vue 项目中创建一个登录表单组件,包含用户名和密码输入框以及提交按钮。可以使用 Vue 的模板语法和双…

vue实现拖拉

vue实现拖拉

实现拖拽功能的基本步骤 在Vue中实现拖拽功能可以通过原生HTML5的拖放API或第三方库如vuedraggable完成。以下是两种方法的详细说明。 使用HTML5原生拖放API HTML5提供了原…

vue实现框选

vue实现框选

Vue 实现框选功能 在 Vue 中实现框选功能通常需要监听鼠标事件,计算选区范围,并根据选区范围高亮或选中元素。以下是实现框选功能的关键步骤。 监听鼠标事件 在 Vue 模板中,为容器元素绑定鼠标…