当前位置:首页 > VUE

原生加数组实现vue

2026-02-23 08:58:49VUE

原生 JavaScript 加数组实现 Vue 核心功能

使用原生 JavaScript 和数组模拟 Vue 的核心功能(如数据绑定、响应式更新)可以通过以下方式实现:

数据劫持与响应式

通过 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(); // 触发更新
      }
    });
  });
}

依赖收集与派发更新

实现简单的发布-订阅模式管理依赖:

原生加数组实现vue

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}
Dep.target = null; // 静态属性指向当前 Watcher

观察者(Watcher)

连接数据与视图的桥梁:

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

数组方法劫持

重写数组原型方法以实现响应式:

原生加数组实现vue

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    const ob = this.__ob__;
    let inserted;
    if (['push', 'unshift', 'splice'].includes(method)) {
      inserted = args.slice(0, method === 'splice' ? args[1] : args.length);
    }
    if (inserted) ob.observeArray(inserted);
    ob.dep.notify(); // 触发更新
    return result;
  };
});

简易模板编译

通过正则匹配实现模板插值:

function compile(el, vm) {
  vm.$el = document.querySelector(el);
  const fragment = document.createDocumentFragment();
  let child;
  while (child = vm.$el.firstChild) {
    fragment.appendChild(child);
  }
  function replace(frag) {
    Array.from(frag.childNodes).forEach(node => {
      const txt = node.textContent;
      const reg = /\{\{\s*(.*?)\s*\}\}/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 && node.childNodes.length) {
        replace(node);
      }
    });
  }
  replace(fragment);
  vm.$el.appendChild(fragment);
}

整合实现

最终组合成简易 Vue 类:

class Vue {
  constructor(options) {
    this.$options = options;
    this.$data = options.data();
    observe(this.$data);
    Object.keys(this.$data).forEach(key => {
      Object.defineProperty(this, key, {
        get() {
          return this.$data[key];
        },
        set(newVal) {
          this.$data[key] = newVal;
        }
      });
    });
    compile(options.el, this);
  }
}

使用示例

<div id="app">
  {{ message }}
  <div>{{ count }}</div>
</div>

<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        message: 'Hello Vue',
        count: 0
      };
    }
  });
  setInterval(() => vm.count++, 1000);
</script>

这种方法实现了 Vue 最基础的数据响应式、依赖收集和模板编译功能,实际 Vue 的实现还包含虚拟 DOM、组件系统等更复杂的机制。

标签: 数组vue
分享给朋友:

相关文章

vue实现fullpage

vue实现fullpage

Vue 实现 FullPage 效果 在 Vue 中实现全屏滚动(FullPage)效果可以通过多种方式完成,以下是几种常见的方法: 使用现有库 vue-fullpage.js 安装 vue-ful…

vue实现波形

vue实现波形

实现波形效果的方法 在Vue中实现波形效果可以通过多种方式完成,常见的方法包括使用Canvas绘制、CSS动画或第三方库。以下是几种实现方案: 使用Canvas绘制波形 通过Canvas API动态…

vue实现答辩

vue实现答辩

Vue 实现答辩系统的关键步骤 项目初始化与配置 使用 Vue CLI 或 Vite 创建项目,安装 Vue Router 管理路由,Pinia/Vuex 进行状态管理。配置 ESLint 和 Pre…

vue实现treeselect

vue实现treeselect

Vue TreeSelect 实现方法 使用 Vue 实现 TreeSelect 组件可以通过以下几种方式完成,包括使用现成的第三方库或自行封装组件。 使用第三方库 推荐使用成熟的第三方 Tree…

vue实现网站

vue实现网站

Vue 实现网站的基本步骤 Vue.js 是一个渐进式 JavaScript 框架,适合构建现代化的单页应用(SPA)或动态网站。以下是使用 Vue 实现网站的基本方法。 初始化 Vue 项目 使…

vue实现筛选

vue实现筛选

实现筛选功能的基本思路 在Vue中实现筛选功能通常需要结合数据绑定、计算属性和方法。筛选的核心逻辑是根据用户输入的条件过滤原始数据列表,并动态更新显示结果。 数据准备 定义一个数组存储原始数据,另一…