手写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.mzph.cn/web/68105.shtml

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

相关文章

spy-debugger + Charles 调试移动端/内嵌小程序H5

简介说明: PC端可以用F12进行console等进行调试,但移动端App中使用webview就无法进行实时调试,针对这种情况 1. 安装 全局安装 spy-debugger sudo npm install spy-debugger -g // window不用加sudo2. spy-debugger 证书 其实spy-debugg…

【目标检测】模型验证:K-Fold 交叉验证

K-Fold 交叉验证 1、引言1.1 K 折交叉验证概述 2、配置2.1 数据集2.2 安装包 3、 实战3.1 生成物体检测数据集的特征向量3.2 K 折数据集拆分3.3 保存记录3.4 使用 K 折数据分割训练YOLO 4、总结 1、引言 我们将利用YOLO 检测格式和关键的Python 库(如 sklearn、pan…

Android studio ternimal 中gradle 指令失效(gradle环境变量未配置)

默认gradle路径:C:\Users\ylwj.gradle\wrapper\dists\gradle-8.10.2-bin\a04bxjujx95o3nb99gddekhwo\gradle-8.10.2\bin 环境变量-系统环境变量-双击path-配置上即可-注意重启studio才会生效

Axure大屏可视化动态交互设计:解锁数据魅力,引领决策新风尚

可视化组件/模板预览:https://8dge09.axshare.com 一、大屏可视化技术概览 在数据驱动决策的时代,大屏可视化技术凭借直观、动态的展示方式,已成为众多行业提升管理效率和优化决策过程的关键工具。它能够将复杂的数据转化为易于理解的图形和…

Resnet 改进:尝试在不同位置加入Transform模块

目录 1. TransformerBlock 2. resnet 3. 替换部分卷积层 4. 在特定位置插入Transformer模块 5. 使用Transformer全局特征提取器 6. 其他 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. TransformerBlock TransformerBlock是Transfo…

MySQL调优02 - SQL语句的优化

SQL语句的优化 文章目录 SQL语句的优化一:SQL优化的小技巧1:编写SQL时的注意点1.1:查询时尽量不要使用*1.2:连表查询时尽量不要关联太多表1.3:多表查询时一定要以小驱大1.4:like不要使用左模糊或者全模糊1.…

langchain教程-12.Agent/工具定义/Agent调用工具/Agentic RAG

前言 该系列教程的代码: https://github.com/shar-pen/Langchain-MiniTutorial 我主要参考 langchain 官方教程, 有选择性的记录了一下学习内容 这是教程清单 1.初试langchain2.prompt3.OutputParser/输出解析4.model/vllm模型部署和langchain调用5.DocumentLoader/多种文档…

大模型中提到的超参数是什么

在大模型中提到的超参数是指在模型训练之前需要手动设置的参数,这些参数决定了模型的训练过程和最终性能。超参数与模型内部通过训练获得的参数(如权重和偏置)不同,它们通常不会通过训练自动学习,而是需要开发者根据任…

位运算及常用技巧

涉及位运算的运算符如下表所示: 位运算的运算律: 负数的位运算 首先,我们要知道,在计算机中,运算是使用的二进制补码,而正数的补码是它本身,负数的补码则是符号位不变,其余按位取反…

hot100(8)

71.10. 正则表达式匹配 - 力扣(LeetCode) 动态规划 题解:10. 正则表达式匹配题解 - 力扣(LeetCode) 72.5. 最长回文子串 - 力扣(LeetCode) 动态规划 1.dp数组及下标含义 dp[i][j] : 下标i到…

二进制/源码编译安装httpd 2.4,提供系统服务管理脚本并测试

方法一:使用 systemd 服务文件 安装所需依赖 yum install gcc make apr-devel apr-util-devel pcre-devel 1.下载源码包 wget http://archive.apache.org/dist/httpd/httpd-2.4.62.tar.gz 2.解压源码 tar -xf httpd-2.4.62.tar.gz cd httpd-2.4.62 3.编译安装 指定…

Java 中 LinkedList 的底层源码

在 Java 的集合框架中,LinkedList是一个独特且常用的成员。它基于双向链表实现,与数组结构的集合类如ArrayList有着显著差异。深入探究LinkedList的底层源码,有助于我们更好地理解其工作原理和性能特点,以便在实际开发中做出更合适…

金蝶云星空k3cloud webapi报“java.lang.Class cannot be cast to java.lang.String”的错误

最近在对接金蝶云星空k3cloud webapi时,报一个莫名其妙的转换异常,具体如下: 同步部门异常! ERP接口登录异常:java.lang.Class cannot be cast to java.lang.String at com.jkwms.k3cloudSyn.service.basics.DeptK3CloudService.…

【Android】jni开发之导入opencv和libyuv来进行图像处理

做视频图像处理时需要对其进行水印的添加,放在应用层调用工具性能方面不太满意,于是当下采用opencvlibyuv方法进行处理。 对于Android的jni开发不是很懂,我的需求是导入opencv方便在cpp中调用,但目前找到的教程都是把opencv作为模…

【MySQL】centos 7 忘记数据库密码

vim /etc/my.cnf文件; 在[mysqld]后添加skip-grant-tables(登录时跳过权限检查) 重启MySQL服务:sudo systemctl restart mysqld 登录mysql,输入mysql –uroot –p;直接回车(Enter) 输…

国产编辑器EverEdit - 自定义标记使用详解

1 自定义标记使用详解 1.1 应用场景 当阅读日志等文件,用于调试或者检查问题时,往往日志中会有很多关键性的单词,比如:ERROR, FATAL等,但由于文本模式对这些关键词并没有突出显示,造成检查问题时&#xff…

Golang 并发机制-6:掌握优雅的错误处理艺术

并发编程可能是提高软件系统效率和响应能力的一种强有力的技术。它允许多个工作负载同时运行,充分利用现代多核cpu。然而,巨大的能力带来巨大的责任,良好的错误管理是并发编程的主要任务之一。 并发代码的复杂性 并发编程增加了顺序程序所不…

JVM 四虚拟机栈

虚拟机栈出现的背景 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多…

鼠标拖尾特效

文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果,能够为网页增添独特的视觉体验。它通常通过JavaScript和C…

6-图像金字塔与轮廓检测

文章目录 6.图像金字塔与轮廓检测(1)图像金字塔定义(2)金字塔制作方法(3)轮廓检测方法(4)轮廓特征与近似(5)模板匹配方法6.图像金字塔与轮廓检测 (1)图像金字塔定义 高斯金字塔拉普拉斯金字塔 高斯金字塔:向下采样方法(缩小) 高斯金字塔:向上采样方法(放大)…