手写MVVM框架-实现简单的数据代理

MVVM框架最显著的特点就是虚拟dom和响应式的数据、我们以Vue为例,分别实现data、computed、created、methods以及虚拟dom。

这一章我们先实现简单的响应式,修改数据之后在控制台打印。

我们将该框架命名为MiniVue。

首先我们需要创建MiniVue的类(src/core/index.js)

创建完类之后我们需要创建一个js(src/core/init.js)给这个类的原型添加初始化事件,用来初始化data、computed等内容

然后在类中混入_init 方法并在构造方法中调用_init方法

接着我们来实现一个数据代理的一部分

 当前的代理我们使用Object.defineProperty来实现,这个类方法有一个很大的缺点,就是在定义数组时,通过下标修改数据和新增删除数据时不会触发,vue2中的解决方法就是重写这些方法,这里我们也按照vue2的方式来实现。

我们在src中添加proxy.js,并添加代理方法(src/core/proxy.js)

/*** 代理数据* @param {*} vm * @param {*} data * @param {*} namespace 主要控制当前data是哪一个 name 还是 object.name 访问跟下面的属性就是 '' */
export function constructProxy(vm, data, namespace) {let proxyObj = {}// 我们需要判断data的类型if(data instanceof Array) { // 需要先判断Array类型} else if (data instanceof Object) { // 判断Object类型proxyObj = proxyObject(vm, data)} else {throw new Error('data must be an object or array')}return proxyObj
}

在响应式系统里面我们只代理Object和Array类型,如果不是就抛出错误

接下来我们来实现Object类型的代理 proxyObject 方法 (src/core/proxy.js)

/*** 代理Object数据* @param {*} vm * @param {*} data */
function proxyObject(vm, data) {// 创建代理对象let proxyObj = {}for(let key in data) {Object.defineProperty(proxyObj, key, {get() {return data[key]},set(newValue) {console.log(`正在修改:${key} 值为:${data[key]}`)data[key] = newValue}})// 为MiniVue的根实例添加属性Object.defineProperty(vm, key, {get() {return data[key]},set(newValue) {console.log(`正在修改根:${key} 值为:${data[key]}`)data[key] = newValue}})}return proxyObj
}

然后我们在初始化方法中去代理data (src/core/init.js)


/*** 实现init方法* @param {Object} options */
function init(options) {console.log(`options: ${options}`)// 初始化dataif(options && options.data) {this._data = constructProxy(this, options.data, "")}// 初始化computed// 初始化methods// 初始化created// 挂载dom
}

这样一个简单的代理就完成了,我们创建一个入口文件并实例化这个MiniVue来看效果

在控制台查看MiniVue实例的属性 然后修改_data 中的数据

我们通过图片内容可以看到:

1.我们可以看到实例中最外层有name 和 description ,这说明我们已经为MiniVue实例的根实例添加了属性

2.我们可以看到_data 中也添加了属性

3.修改根节点的name 后 _data.name 也会发生了变化,并且监控到了修改行为

章节总结:

1.创建MiniVue类,创建init.js 给原型添加_init方法

2.在方法中实现data、computed、created、methods以及虚拟dom

3.创建proxy.js, 入口方法中判断数据类型 如果不是Object 或者 Array 直接抛出异常

4.代理Object类型时, 创建代理对象,并且给实例的根属性也添加代理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/12288.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESLint

ESLint ESLint 是一个针对 JS 的代码风格检查工具,当不满足其要求的风格时,会给予警告或错误。 官网:https://eslint.org/ 中文网:https://eslint.nodejs.cn/ 安装使用 在你的项目中安装 ESLint 包: npm install -…

kaggle视频行为分析1st and Future - Player Contact Detection

这次比赛的目标是检测美式橄榄球NFL比赛中球员经历的外部接触。您将使用视频和球员追踪数据来识别发生接触的时刻,以帮助提高球员的安全。两种接触,一种是人与人的,另一种是人与地面,不包括脚底和地面的,跟我之前做的这…

Chapter 6 -Fine-tuning for classification

Chapter 6 -Fine-tuning for classification 本章内容涵盖 引入不同的LLM微调方法准备用于文本分类的数据集修改预训练的 LLM 进行微调微调 LLM 以识别垃圾邮件评估微调LLM分类器的准确性使用微调的 LLM 对新数据进行分类 现在,我们将通过在大语言模型上对特定目标任…

【从零开始的LeetCode-算法】922. 按奇偶排序数组 II

给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。 对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。 你可以返回 任何满足上述条件的…

python 小游戏:扫雷

目录 1. 前言 2. 准备工作 3. 生成雷区 4. 鼠标点击扫雷 5. 胜利 or 失败 6. 游戏效果展示 7. 完整代码 1. 前言 本文使用 Pygame 实现的简化版扫雷游戏。 如上图所示,游戏包括基本的扫雷功能:生成雷区、左键点击扫雷、右键标记地雷、显示数字提示…

安全策略实验报告

1.实验拓扑图 2.实验需求 vlan2属于办公区,vlan3生产区 办公区pc在工作日时间可以正常访问OAserver,i其他时间不允许 办公区pc可以在任意时间访问Web server 生产区pc可以在任意时间访问OA server但不能访问web server 特例:生产区pc可以…

力扣73矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 输入:matrix [[0,1,2,0],[3,4,5,2],[…

蓝桥杯C语言组:暴力破解

基于C语言的暴力破解方法详解 暴力破解是一种通过穷举所有可能的解来找到正确答案的算法思想。在C语言中,暴力破解通常用于解决那些问题规模较小、解的范围有限的问题。虽然暴力破解的效率通常较低,但它是一种简单直接的方法,适用于一些简单…

【自然语言处理(NLP)】生成词向量:GloVe(Global Vectors for Word Representation)原理及应用

文章目录 介绍GloVe 介绍核心思想共现矩阵1. 共现矩阵的定义2. 共现概率矩阵的定义3. 共现概率矩阵的意义4. 共现概率矩阵的构建步骤5. 共现概率矩阵的应用6. 示例7. 优缺点优点缺点 **总结** 目标函数训练过程使用预训练的GloVe词向量 优点应用总结 个人主页:道友老…

介绍一下Mybatis的Executor执行器

Executor执行器是用来执行我们的具体的SQL操作的 有三种基本的Executor执行器: SimpleExecutor简单执行器 每执行一次update或select,就创建一个Statement对象,用完立刻关闭Statement对象 ReuseExecutor可重用执行器 可重复利用Statement…

Autosar-以太网是怎么运行的?(Davinci配置部分)

写在前面: 入行一段时间了,基于个人理解整理一些东西,如有错误,欢迎各位大佬评论区指正!!! 目录 1.Autosar ETH通讯软件架构 2.Ethernet MCAL配置 2.1配置对应Pin属性 2.2配置TXD引脚 2.3配…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户登录

🧸安清h:个人主页 🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎯1.登录-持久层 &…

VSCode设置内容字体大小

1、打开VSCode软件,点击左下角的“图标”,选择“Setting”。 在命令面板中的Font Size处选择适合自己的字体大小。 2、对比Font Size值为14与20下的字体大小。

企业商业秘密百问百答之三十八【商务保密协议签订】

《企业商业秘密百问百答》是由天禾律所陈军律师团队精心编撰的成果,汇集了该团队律师在处理商业秘密相关的刑事和民事案件中的丰富经验。近年来,这份资料已通过线上和线下的方式向全国近千家企业进行了广泛宣讲,并获得了积极的社会反响。 其…

C++11中的bind

官方文档对于bind接口的概述解释:Bind function arguments 在C11中,std::bind 是一个非常有用的工具,用于将函数、成员函数或函数对象与特定的参数绑定在一起,生成一个新的可调用对象。std::bind 可以用于部分应用函数参数、改变…

Qt网络相关

“ 所有生而孤独的人,葆有的天真 ” 为了⽀持跨平台, QT对⽹络编程的 API 也进⾏了重新封装。本章会上手一套基于QT的网络通信编写。 UDP Socket 在使用Qt进行网络编程前,需要在Qt项目中的.pro文件里添加对应的网络模块( network ). QT core gui net…

会计学基础

【拯救者】会计学基础速成(期末 复试 升本均可用) ©无忌教育 重点: 适用课本: 会计基础 会计基础是指会计工作的基本原则和方法,它努力为会计核算提供一个共同的基础,以便各种组织在会计核算上得到一致的结果。会计基础主要…

我们信仰AI?从神明到人工智能——信任的进化

信任的进化: 信任是我们最宝贵的资产。而现在,它正像黑色星期五促销的廉价平板电视一样,被一点点拆解。在过去,世界很简单:人们相信晚间新闻、那些满是灰尘书籍的教授,或者手持病历、眉头紧锁的医生。而如…

《DeepSeek R1:7b 写一个python程序调用摄像头获取视频并显示》

C:\Users\Administrator>ollama run deepseek-r1:7b hello Hello! How can I assist you today? 😊 写一个python程序调用摄像头获取视频并显示 好,我需要帮用户写一个Python程序,它能够使用摄像头获取视频,并在屏幕上显示出…

Linux网络 | 进入数据链路层,学习相关协议与概念

前言:本节内容进入博主讲解的网络层级中的最后一层:数据链路层。 首先博主还是会线代友友们认识一下数据链路层的报文。 然后会带大家重新理解一些概念,比如局域网交换机等等。然后就是ARP协议。 讲完这些, 本节任务就算结束。 那…