当前位置:首页 > VUE

js 实现vue

2026-01-08 00:55:48VUE

实现 Vue 的核心功能

在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路:

响应式系统

通过 Object.definePropertyProxy 实现数据劫持,监听数据变化并触发更新。

js 实现vue

class Observer {
  constructor(data) {
    this.walk(data);
  }

  walk(data) {
    if (!data || typeof data !== 'object') return;
    Object.keys(data).forEach(key => {
      this.defineReactive(data, key, data[key]);
    });
  }

  defineReactive(obj, key, val) {
    const dep = new Dep();
    this.walk(val);
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get() {
        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());
  }
}

Dep.target = null;

虚拟 DOM 与渲染

实现一个简单的虚拟 DOM 和渲染函数。

js 实现vue

class VNode {
  constructor(tag, data, children, text) {
    this.tag = tag;
    this.data = data;
    this.children = children;
    this.text = text;
  }
}

function render(vnode, container) {
  const el = document.createElement(vnode.tag);
  for (const key in vnode.data) {
    el.setAttribute(key, vnode.data[key]);
  }
  if (vnode.text) {
    el.textContent = vnode.text;
  } else if (vnode.children) {
    vnode.children.forEach(child => {
      render(child, el);
    });
  }
  container.appendChild(el);
}

组件系统

实现一个简单的组件系统,将模板、数据和方法封装在一起。

class Vue {
  constructor(options) {
    this.$options = options;
    this._data = options.data();
    new Observer(this._data);
    this.compile(options.el);
  }

  compile(el) {
    const element = document.querySelector(el);
    this.compileNode(element);
  }

  compileNode(node) {
    if (node.nodeType === 1) {
      Array.from(node.attributes).forEach(attr => {
        if (attr.name.startsWith('v-')) {
          const dir = attr.name.substring(2);
          this[dir](node, attr.value);
        }
      });
      node.childNodes.forEach(child => this.compileNode(child));
    } else if (node.nodeType === 3) {
      const reg = /\{\{(.*?)\}\}/g;
      const text = node.textContent;
      if (reg.test(text)) {
        const key = RegExp.$1.trim();
        new Watcher(this._data, key, (newVal) => {
          node.textContent = text.replace(reg, newVal);
        });
        node.textContent = text.replace(reg, this._data[key]);
      }
    }
  }

  model(node, key) {
    node.value = this._data[key];
    new Watcher(this._data, key, (newVal) => {
      node.value = newVal;
    });
    node.addEventListener('input', (e) => {
      this._data[key] = e.target.value;
    });
  }
}

Watcher 实现

Watcher 用于连接响应式数据和视图更新。

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

  update() {
    this.cb(this.value);
  }
}

使用示例

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

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

实现要点

  • 数据劫持:使用 Object.definePropertyProxy 监听数据变化。
  • 依赖收集:通过 DepWatcher 管理依赖关系。
  • 模板编译:解析模板中的指令和插值表达式,绑定数据和事件。
  • 虚拟 DOM:简化版的虚拟 DOM 实现,用于高效更新视图。

以上代码展示了 Vue 的核心功能实现,包括响应式数据、模板编译和虚拟 DOM。实际 Vue 的实现更为复杂,包含更多优化和功能。

标签: jsvue
分享给朋友:

相关文章

vue实现单选

vue实现单选

Vue 实现单选功能 在 Vue 中实现单选功能可以通过多种方式完成,以下是几种常见的方法: 使用 v-model 绑定单选按钮 通过 v-model 绑定一个变量,可以实现单选功能。单选按钮的 v…

vue实现年历

vue实现年历

Vue 实现年历的方法 使用 Vue 实现年历可以通过组件化开发方式,结合日期计算和动态渲染完成。以下是两种常见的实现方式: 基于原生 Vue 的日历组件 创建 Calendar.vue 组件文件…

vue实现多级弹窗

vue实现多级弹窗

Vue 多级弹窗实现方法 方法一:使用动态组件与递归组件 在 Vue 中可以通过动态组件配合递归组件实现多级弹窗。定义一个基础弹窗组件,通过递归调用自身实现层级嵌套。 基础弹窗组件模板示例:…

vue实现多个tab

vue实现多个tab

Vue 实现多个 Tab 的方法 使用动态组件切换 在 Vue 中可以通过动态组件 <component :is="currentTab"> 结合 v-for 和 v-bind 实现多个…

vue前端实现注册

vue前端实现注册

使用 Vue 实现用户注册功能 环境准备 确保已安装 Vue CLI 或通过 CDN 引入 Vue。若使用 Vue CLI,需安装 axios 或其他 HTTP 库用于后端通信。 注册表单组件 创建…

vue实现适老化样式

vue实现适老化样式

Vue 实现适老化样式的关键方法 全局字体与字号调整 通过 CSS 变量或主题配置统一放大基础字号,建议正文不小于 18px,标题更大。在 App.vue 中设置全局样式: :root { -…