当前位置: 首页 > ds >正文

Vue 数据代理机制实现

Vue 数据代理机制实现

以下是符合 Vue 核心原理的简化版数据代理实现:

class Vue {constructor(options) {// 1. 创建内部数据存储对象this._data = options.data || {};// 2. 执行数据代理this._proxyData();}// 数据代理核心方法_proxyData() {Object.keys(this._data).forEach(key => {// 3. 跳过 Vue 保留属性 (以 _ 或 $ 开头)if (key.startsWith('_') || key.startsWith('$')) {console.warn(`[Vue warn]: Property "${key}" must be accessed via $data because it starts with a reserved character.`);return;}// 4. 使用 defineProperty 建立代理Object.defineProperty(this, key, {enumerable: true,configurable: true,get: () => {console.log(`[get] ${key}: ${this._data[key]}`);return this._data[key];},set: (newVal) => {console.log(`[set] ${key}: ${newVal}`);this._data[key] = newVal;// 实际 Vue 这里会触发响应式更新// this._updateView(); }});});}
}// 使用示例
const vm = new Vue({data: {message: "Hello Vue",count: 0,// 以下属性不会被代理_internal: "secret",$private: "data"}
});// 正常代理属性
console.log(vm.message); // "Hello Vue"
vm.count = 5;            // 设置新值// 保留属性无法通过代理访问
console.log(vm._internal); // undefined (控制台会有警告)
console.log(vm.$private);  // undefined

关键实现说明:

  1. 内部数据存储
    使用 _data 属性存储原始数据(Vue 实际实现方式)

  2. 保留属性过滤
    跳过以 _$ 开头的属性(Vue 内部保留标识符)

  3. 代理机制核心

    • 使用 Object.defineProperty 创建响应式代理
    • getter 返回 _data 中的对应值
    • setter 更新 _data 中的值
  4. 响应式扩展点
    在 setter 中预留了视图更新接口(实际 Vue 会在这里触发依赖更新)

实际 Vue 实现的优化点:

  1. 嵌套对象处理
    Vue 会递归遍历嵌套对象进行代理

  2. 数组方法重写
    拦截数组的变异方法(push/pop/shift 等)

  3. 依赖收集系统
    在 getter 中收集依赖(Watcher)

  4. 异步更新队列
    使用 nextTick 批量更新视图

  5. 代理冲突检测
    检查是否与 Vue 实例方法重名(如 $emit

完整版增强实现(包含嵌套代理):

class Vue {constructor(options) {this._data = options.data || {};this._proxyData(this, this._data);}_proxyData(target, data) {Object.keys(data).forEach(key => {// 跳过保留属性if (key.startsWith('_') || key.startsWith('$')) return;// 递归处理嵌套对象if (typeof data[key] === 'object' && data[key] !== null) {this._proxyData(data[key], data[key]);}Object.defineProperty(target, key, {get: () => data[key],set: (newVal) => {// 处理新值为对象的情况if (typeof newVal === 'object') {this._proxyData(newVal, newVal);}data[key] = newVal;}});});}
}

这个实现包含了 Vue 数据代理的核心思想:通过 Object.defineProperty 建立 data 对象与 Vue 实例的访问通道,同时处理了嵌套对象和保留属性的特殊情况。实际 Vue 源码还包含完善的依赖收集和派发更新机制(Dep/Watcher 系统)。

http://www.xdnf.cn/news/13626.html

相关文章:

  • 什么是数据交换?有哪些数据交换方式?
  • Rust 学习笔记:关于 Future trait 和 Async 语法的练习题
  • el-select滚动分页加载、模糊搜索
  • 代码填空题技术实现:突破 highlight.js 安全限制的工程实践
  • Java Collection接口解析
  • c++算法学习6——迪杰斯特拉算法
  • 用 OpenSSL 库实现 3DES(三重DES)加密
  • CKA考试知识点分享(10)---NetworkPolicy
  • 【Git】TortiseGit设置过滤上传文件
  • 神经网络:深度剖析过拟合、欠拟合及其泛化能力提升策略
  • 【学习笔记】HTTP
  • P2834 纸币问题 3
  • 讲一件Java虚拟线程
  • 小白理财 - 入门第一课
  • 扁平风格职场商务通用PPT模版分享
  • AI支持下的-ArcGIS数据处理、空间分析、可视化及多案例综合应用
  • Java多线程实现之同步方法详解
  • Win10重装系统 (重生篇:我在华强修电脑)
  • 用python玩转大语言模型——从 RNN 到文本生成大语言模型的奇幻之旅
  • SpringBoot学习day2-前后端的交互搭建以及跨域问题、拦截过滤器问题的解决
  • 理解系统交互:UML时序图
  • 驭码CodeRider 2.0 产品体验:在VSCode安装并创建一个雷电小游戏
  • Django项目QQ授权登录报错:redirect uri is illegal(100010) 解决方法
  • 深度学习小项目合集之音频语音识别
  • docker-compose搭建eureka-server和zipkin
  • ubuntu 安装 JDK8
  • 安信可(云知声蜂鸟US516P6)SDK开发学习---log日志打印子系统模块
  • 云原生安全实践:CI/CD流水线集成DAST工具
  • 【PostgreSQL系列】PostgreSQL WAL 目录配置
  • 力扣HOT100之贪心算法:45. 跳跃游戏 II