手撸一个Vue(看不懂可以举报)
手撸一个Vue(看不懂可以举报)作为编程讲师我深知很多同学对Vue的响应式原理充满好奇却又望而却步。今天我们就从零开始一步一步“手撸”一个简化版的Vue。如果你看完还看不懂欢迎举报我但请相信跟着代码走一遍你会发现自己比想象中更强大。## 什么是Vue的核心Vue的核心是“响应式数据”和“模板渲染”。简单来说就是当数据变化时视图自动更新。要实现这个我们需要解决三个问题1.如何监听数据变化—— 使用Object.definePropertyVue2或ProxyVue3。2.如何知道哪些视图依赖了哪些数据—— 通过“依赖收集”。3.数据变化时如何更新视图—— 触发更新函数。我们先从最简单的版本开始一步步完善。## 第一步监听数据变化基础版我们先用Object.defineProperty实现数据监听。这个API可以拦截对象的读取和赋值操作。javascript// 监听对象的所有属性function observe(obj) { if (typeof obj ! object || obj null) return; Object.keys(obj).forEach(key { let value obj[key]; // 递归监听嵌套对象 observe(value); Object.defineProperty(obj, key, { get() { console.log(读取属性 ${key}: ${value}); return value; }, set(newVal) { if (newVal ! value) { console.log(更新属性 ${key}: ${value} - ${newVal}); value newVal; // 如果新值是对象继续监听 observe(newVal); } } }); });}// 测试const data { name: 小明, age: 18 };observe(data);data.name 小红; // 输出更新属性 name: 小明 - 小红console.log(data.name); // 输出读取属性 name: 小红运行这段代码你会发现每次读取或修改属性时控制台都会打印信息。这就是Vue2响应式的底层基础。## 第二步依赖收集中级版光监听数据还不够我们需要知道“谁”依赖了这个数据。比如模板中用到了{{ name }}那么当name变化时就要重新渲染这个模板片段。这里我们引入一个“依赖管理器”——DepDependency每个属性都有一个Dep实例。当读取属性时把当前的“观察者”Watcher加入依赖列表当属性变化时通知所有观察者更新。javascript// 依赖管理器class Dep { constructor() { this.subs []; // 存储所有观察者 } // 添加观察者 addSub(watcher) { this.subs.push(watcher); } // 通知所有观察者 notify() { this.subs.forEach(watcher watcher.update()); }}// 观察者代表一个需要更新的视图片段class Watcher { constructor(obj, key, callback) { this.obj obj; this.key key; this.callback callback; // 在读取属性前先把当前Watcher存入全局 Dep.target this; // 触发getter把当前Watcher加入依赖 obj[key]; Dep.target null; } update() { console.log(属性 ${this.key} 变化了执行更新); this.callback(); }}// 改造observe函数为每个属性创建Depfunction observe(obj) { if (typeof obj ! object || obj null) return; Object.keys(obj).forEach(key { let value obj[key]; const dep new Dep(); // 每个属性有自己的Dep observe(value); Object.defineProperty(obj, key, { get() { // 如果当前有Watcher在读取就加入依赖 if (Dep.target) { dep.addSub(Dep.target); } return value; }, set(newVal) { if (newVal ! value) { value newVal; observe(newVal); dep.notify(); // 通知所有观察者 } } }); });}// 测试const data { name: 小明 };observe(data);// 创建一个观察者依赖data.namenew Watcher(data, name, () { console.log(视图更新显示新名字);});data.name 小红; // 输出属性 name 变化了执行更新// 输出视图更新显示新名字现在当data.name变化时对应的观察者就会执行更新函数。这就是Vue依赖收集的雏形。## 第三步实现微型Vue高级版现在我们把上面的概念组合成一个微型Vue类。它接收一个选项对象包含data和el挂载元素并解析模板中的{{}}插值。javascriptclass MiniVue { constructor(options) { this.$options options; this.$data options.data; // 1. 监听数据 observe(this.$data); // 2. 编译模板 this.$el document.querySelector(options.el); this.compile(this.$el); } // 编译模板替换{{}}为数据 compile(node) { const childNodes node.childNodes; childNodes.forEach(child { if (child.nodeType 3) { // 文本节点 const oldText child.textContent; const reg /\{\{(.*?)\}\}/g; // 匹配{{key}} if (reg.test(oldText)) { // 提取变量名 const key RegExp.$1.trim(); // 创建观察者数据变化时更新文本 new Watcher(this.$data, key, () { child.textContent oldText.replace(reg, this.$data[key]); }); // 初始化渲染 child.textContent oldText.replace(reg, this.$data[key]); } } else if (child.nodeType 1) { // 元素节点递归编译 this.compile(child); } }); }}// 使用微型Vueconst app new MiniVue({ el: #app, data: { message: Hello Vue!, count: 0 }});// 3秒后修改数据视图自动更新setTimeout(() { app.$data.message Hello MiniVue!;}, 3000);对应的HTMLhtmldiv idapp p{{ message }}/p p{{ count }}/p/div运行这段代码你会看到页面显示“Hello Vue!”3秒后自动变成“Hello MiniVue!”。恭喜你你已经手撸了一个微型Vue## 第四步进阶思考我们的微型Vue还有哪些不足1.不支持数组Object.defineProperty无法监听数组索引变化Vue2通过重写数组方法解决。2.不支持v-model等指令真正的Vue有复杂的指令系统。3.性能优化模板编译可以生成渲染函数而不是直接操作DOM。4.计算属性和侦听器需要额外的依赖管理。Vue3使用Proxy替代Object.defineProperty可以原生监听数组和动态新增属性性能也更好。## 总结通过本文我们一步步实现了-数据监听使用Object.defineProperty拦截get/set。-依赖收集Dep管理Watcher在get时收集依赖set时通知更新。-模板编译解析{{}}插值创建Watcher实现数据驱动视图。虽然只有100多行代码但已经包含了Vue响应式系统的核心思想。现在你应该明白Vue并不是什么黑魔法而是一套优雅的设计模式。如果你跟着代码写了一遍还是不懂欢迎举报我——但请带上你的代码我们一起debug编程路上动手永远比空想更重要。下次面试官问你Vue原理你可以自信地说“我手撸过一个。”

相关新闻

私域电商做了半年没起色?大概率是这三个环节出了问题

私域电商做了半年没起色?大概率是这三个环节出了问题

私域电商跑了半年还没起色,大概率不是方向错了,而是引流、留存、转化这三个环节里至少有一环在漏水。三环节串成一条漏斗:上游漏一点,到下游就放大成致命缺口。问题不出在执行勤奋度,出在诊断缺失——没人能说清到底哪…

2026/7/31 6:36:21阅读更多 →
MOS管损坏原因深度解析:从栅极驱动到热设计,全面规避硬件失效

MOS管损坏原因深度解析:从栅极驱动到热设计,全面规避硬件失效

1. 项目概述:从一次深夜维修说起 上周,我实验室里一台用了三年的可调直流电源突然罢工了,输出电压时有时无,还伴随着轻微的“嘶嘶”声。拆开一看,主功率变换部分的一颗TO-220封装的MOS管已经“壮烈牺牲”——外壳炸裂&…

2026/7/31 6:36:21阅读更多 →
英伟达Quadro专业显卡全史:从2000到2023的架构演进与选购指南

英伟达Quadro专业显卡全史:从2000到2023的架构演进与选购指南

1. 项目概述与价值解析最近在整理工作室的旧设备,翻出来好几张老Quadro显卡,从早期的FX系列到后来的P系列都有。看着这些“老伙计”,突然意识到,虽然现在大家聊得更多的是GeForce RTX,但在专业图形工作站领域&#xff…

2026/7/31 6:36:21阅读更多 →
Cocos Creator帧动画组件开发:从原理到高性能实现

Cocos Creator帧动画组件开发:从原理到高性能实现

1. 项目概述:为什么我们需要一个自定义的帧动画播放组件? 在Cocos Creator项目中处理动画,尤其是序列帧动画,是每个开发者都会遇到的常规需求。引擎内置的 Sprite 组件配合 SpriteFrame 数组,或者使用 Animation …

2026/7/31 7:54:49阅读更多 →
齿轮泵噪音大怎么降低分贝 专业科普降低噪音的有效方法

齿轮泵噪音大怎么降低分贝 专业科普降低噪音的有效方法

矿山、工程机械、装载机、石油修井机等重工场景中,液压系统长期处于重载冲击、高频作业、粉尘潮湿的恶劣环境,齿轮泵作为核心动力部件,极易出现噪音过大、供油不稳、压力不足、油液渗漏等问题。异常噪音不仅污染作业环境,更是设备…

2026/7/31 7:54:49阅读更多 →
C++结构体实战:从数据孤岛到关系映射的导师制信息管理

C++结构体实战:从数据孤岛到关系映射的导师制信息管理

1. 项目概述:从“数据孤岛”到“关系映射”的实战演练在C的初学阶段,我们常常会接触到数组、变量这些基础的数据容器,它们能很好地管理单一类型、逻辑简单的数据。但当我们面对现实世界中的复杂实体时,比如一个“带教老师”和他所…

2026/7/31 7:54:49阅读更多 →
HTTP分片下载与断点续传:从协议原理到Python实现

HTTP分片下载与断点续传:从协议原理到Python实现

1. 从一次失败的下载说起:为什么我们需要分片那天下午,我正在从公司内网服务器拉取一个将近10GB的虚拟机镜像文件。进度条缓慢地爬到了78%,网络突然闪断了一下。等我重新连接,发现下载工具弹出了一个冰冷的提示:“网络…

2026/7/31 7:54:49阅读更多 →
Spring WebFlux WebClient文件传输实战:解决缓冲区限制与流式处理

Spring WebFlux WebClient文件传输实战:解决缓冲区限制与流式处理

1. 项目概述:WebClient文件传输的实战与深坑 在微服务架构里,服务间的文件传输是个高频且容易踩坑的场景。特别是当你从传统的同步阻塞式框架(比如用 RestTemplate )转向响应式编程栈,使用Spring WebFlux的 WebClie…

2026/7/31 7:54:48阅读更多 →
RaDIO系统:大语言模型实时幻觉检测技术解析

RaDIO系统:大语言模型实时幻觉检测技术解析

1. 项目概述:RaDIO如何革新大语言模型的幻觉检测 在AAAI 2025大会上,浙师大与港科大联合团队发布的RaDIO系统,可能是当前解决大语言模型(LLM)幻觉问题最实用的方案。作为长期跟踪LLM落地的从业者,我亲测过数…

2026/7/31 7:52:48阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/30 15:03:16阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/30 12:22:27阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/30 15:13:02阅读更多 →
物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:40阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:41阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:41阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/31 0:49:33阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/31 5:08:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/30 15:43:46阅读更多 →