当前位置:首页 > VUE

实现vue vm

2026-03-28 02:32:30VUE

Vue VM 实现

Vue VM(ViewModel)是 Vue.js 的核心部分,负责连接视图(View)与数据模型(Model)。以下是实现 Vue VM 的关键步骤:

数据绑定

通过 Object.definePropertyProxy 实现数据劫持,监听数据变化。当数据变化时,自动更新视图。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      // 触发更新
    }
  });
}

模板编译

将模板转换为渲染函数。使用正则表达式解析模板中的指令(如 v-modelv-if),生成对应的虚拟 DOM。

function compile(template) {
  // 解析模板生成 AST
  const ast = parse(template);
  // 优化 AST
  optimize(ast);
  // 生成渲染函数
  const code = generate(ast);
  return new Function(`with(this){return ${code}}`);
}

依赖收集

通过 DepWatcher 实现依赖收集。每个响应式属性都有一个 Dep 实例,用于存储依赖的 Watcher

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

class Watcher {
  constructor(vm, expOrFn, cb) {
    this.vm = vm;
    this.getter = parsePath(expOrFn);
    this.cb = cb;
    this.value = this.get();
  }
  get() {
    Dep.target = this;
    const value = this.getter.call(this.vm, this.vm);
    Dep.target = null;
    return value;
  }
  update() {
    this.run();
  }
  run() {
    const value = this.get();
    if (value !== this.value) {
      this.value = value;
      this.cb.call(this.vm, value);
    }
  }
}

虚拟 DOM 与 Diff 算法

通过虚拟 DOM 提高渲染效率。当数据变化时,生成新的虚拟 DOM,并通过 Diff 算法比较新旧虚拟 DOM,只更新变化的部分。

function patch(oldVnode, vnode) {
  if (sameVnode(oldVnode, vnode)) {
    patchVnode(oldVnode, vnode);
  } else {
    const parentElm = oldVnode.elm.parentNode;
    createElm(vnode);
    parentElm.insertBefore(vnode.elm, oldVnode.elm);
    parentElm.removeChild(oldVnode.elm);
  }
  return vnode.elm;
}

生命周期管理

实现 Vue 的生命周期钩子,如 createdmountedupdated 等。在适当的时机调用这些钩子函数。

function callHook(vm, hook) {
  const handlers = vm.$options[hook];
  if (handlers) {
    handlers.forEach(handler => handler.call(vm));
  }
}

指令系统

实现常用指令如 v-modelv-forv-if 等。指令负责将数据的变化反映到视图上。

实现vue vm

function bindDirective(el, binding, vnode) {
  switch (binding.name) {
    case 'model':
      el.value = binding.value;
      el.addEventListener('input', e => {
        vnode.context[binding.expression] = e.target.value;
      });
      break;
    // 其他指令处理
  }
}

以上是 Vue VM 的核心实现思路,实际开发中可以使用 Vue.js 官方库,无需手动实现这些功能。

标签: vuevm
分享给朋友:

相关文章

vue 实现在线预览

vue 实现在线预览

Vue 实现在线预览的常见方法 使用 iframe 嵌入 通过 iframe 标签可以嵌入多种类型的文件,如 PDF、图片、网页等。需要确保文件地址可访问。 <template> &…

vue实现div

vue实现div

Vue 实现 DIV 元素的方法 在 Vue 中实现 DIV 元素可以通过多种方式,以下是几种常见的实现方法: 使用模板语法 在 Vue 的模板中直接使用 HTML 的 <div> 标签…

vue实现流程

vue实现流程

Vue 实现流程的基本步骤 安装 Vue.js 可以通过 CDN 引入或使用 npm/yarn 安装。 CDN 方式: <script src="https://cdn.jsdelivr.…

分页实现vue

分页实现vue

分页实现(Vue) 在Vue中实现分页功能通常需要结合前端分页逻辑和后端API支持。以下是两种常见的实现方式: 前端分页实现 适用于数据量较小的情况,直接在客户端完成分页逻辑。 <templ…

vue实现购票

vue实现购票

Vue 实现购票功能 数据结构设计 购票功能通常需要以下数据结构: 场次信息(时间、地点、价格) 座位信息(可选座位、已售座位) 用户订单信息 示例数据结构: data() { return…

vue 实现轮播

vue 实现轮播

Vue 实现轮播的方法 使用第三方库(如 Swiper) 安装 Swiper 库: npm install swiper 在 Vue 组件中引入 Swiper: <template>…