手撕Vue-数据驱动界面改变下

news2024/11/26 7:27:07

经过上一篇的介绍,已经实现了观察者模式的基本内容,接下来要完成的就是将上一篇的发布订阅模式运用到 Nue 中,实现数据驱动界面改变。

在监听数据变化的章节当中,根据指定的区域和数据去编译渲染界面 这个步骤处,我写了一个注释,这个注释是这样的:第一步:给外界传入的所有数据都添加get/set方法,第二步就是在第一步的基础上,给所有属性都添加观察者对象,当数据发生变化时,发布订阅触发观察者对象的回调函数重新渲染界面。

先处理下 v-model 的情况,找到 CompilerUtil 中的 model 方法,将其修改添加观察者对象代码:

model: function (node, value, vm) {
    // 第二部:在第一次渲染的时候, 就给所有的属性添加观察者
    new Watcher(vm, value, (newValue, oldValue) => {
        node.value = newValue;
    });

    node.value = this.getValue(vm, value);
},

这样就完成了第二步,接下来第三步就是将当前属性的所有观察者对象都放到当前属性的发布订阅对象中管理起来

在创建观察者对象的时候,在构造函数当中,会调用 getOldValue 方法,会调用 CompilerUtil.getValue 方法,这个方法就是用于获取属性值的,在编译模板之前已经给所有属性添加了 get/set 方法,所以在获取属性值的时候,就会触发 get 方法,我们就可以在 get 方法中将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来。

在 Observer 类中的 defineRecative 方法中添加如下代码:

defineReactive(obj, attr, value) {
    this.observer(value);

    // 第三步:将当前属性的所有观察者对象都放到当前属性的发布订阅对象中管理起来
    // 创建属于当前属性的发布订阅对象
    let dep = new Dep();

    Object.defineProperty(obj, attr, {
        get() {
            Dep.target && dep.addSub(Dep.target);
            return value;
        },
        set: (newValue) => {
            if (value !== newValue) {
                this.observer(newValue);
                value = newValue;
                dep.notify();
                console.log('监听到数据的变化, 需要去更新UI');
            }
        }
    })
}

在上述代码中,创建了一个属于当前属性的发布订阅对象,然后在 get 方法中,判断 Dep.target 是否存在,如果存在,就将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来。Dep.target 就是当前属性的观察者对象,这里该需要在改造一下观察者的类,将观察者对象添加到 Dep.target 中,放在全局中管理起来。等到所有的属性都添加完观察者对象之后,就将 Dep.target 置为 null。

改造观察者类中的 getOldValue 方法, 这样在 get 方法中就可以将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来了:

getOldValue() {
    Dep.target = this;
    let oldValue = CompilerUtil.getValue(this.vm, this.attr);
    Dep.target = null;
    return oldValue;
}

这样就完成了数据驱动界面改变的功能,接下来我们就来测试一下,打开浏览器控制台,更改下数据,看看是否会触发界面的重新渲染,如下图所示:

image-20231015225532652

好了到此为止,我们已经完成了 v-model 数据驱动界面改变的功能。

下面我将以 debugger 的形式来讲解一下整个数据驱动界面改变的过程, 在 defineReactive get 方法中打上断点,如下图所示:

image-20231015225930152

返回浏览器,主要关注调用栈,如下图所示:

image-20231015230019559

自己从下依次往上看,就可以看到整个数据驱动界面改变的过程了,这里我就不一一截图了,大家可以自己去看一下。

image-20231015230130758

如上是 get 方法代码的执行流程,那么 set 的我也可以说明一下,set 方法的 debugger 不是打在 defineReactive 中,而是打在 Watcher 类中的 update 方法中,所执行的回调函数当中,如下图所示:

image-20231015230405011

返回浏览器,打开控制台更改数据触发 set 方法,发布订阅触发 update 方法:

image-20231015230617621

这次也是主要关注调用栈,自己从下依次往上看,就可以看到整个数据驱动界面改变的过程了,这里我就不一一截图了,大家可以自己去看一下,如下图所示:

image-20231015230547888

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

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

相关文章

20.项目开发之量化交易QuantTrade(二)

项目开发之量化交易QuantTrade(二) 前后端业务:用户登录 业务实现 MemberController /** * 登录用户 * param member * return */ ApiOperation("登录接口") PostMapping("/login") public ResponseBody RestObject login(RequestBody Memb…

浅谈弧光保护在中低压电力系统中的重要性

【摘要】: 中低压电力系统由于无母线保护、出线多,操作频繁、三相导体线间距离和与大地的距离比较近、易受小动物危害、设备制造质量比高压设备差,使其弧光事故的易发性大大高于高压。基于此,本文首先阐述弧光产生的原因及危害&am…

yolov5 + openvino + c++测试

1.拉取最新yolov5代码,训练自己数据或者直接用官方pt模型来进行转为openvino的格式,当前已经支持直接把pt模型转为openvino。 我拉取的是:2023-10-03 21:46 dd9e3382c9af9697fb071d26f1fd1698e9be3e04 在export.py代码中把default中加…

MySQL高级-01.Linux系统下安装MySQL

1.环境配置 首先要准备好两台centos虚拟机,在高级篇部分可能有数据库主从复制,所以暂时先开两台虚拟机。 两台虚拟机需要更改: mac地址主机名ip地址UUID 1.更改主机名 更改虚拟机的主机名 vim /etc/hostname2.更改静态ip地址 /etc/sysc…

PyQt 问题记录

1.现成的组件不一定线程安全,(包括且不限于数据的修改竞争,和一些组件的崩溃 ) 对于PyQt 的线程使用,可能还需要更谨慎些 保存逻辑 QuestionBox("保存/Save")def Save(self):okFlagFalseerrFlagFalseWriteCmd{}for it in self.Mode…

RAII与智能指针

RAII与智能指针 1.RAII1.1RAII理解1.2RAII的原理1.2.1简单的例子说明局部对象的自动销毁的特性 1.2.2 RAII 过程 2.智能指针2.1 auto_ptr2.1.1auto_ptr的使用构造函数与析构函数拷贝构造函数与赋值提领操作auto ptr其它函数 2.1.2autoptr使用的注意事项 2.2 unique_ptr2.2.1uni…

一元函数极值问题

一元函数极值问题 0 引言 在高等数学课程中,我们应该都学习过一元函数的极值问题,这篇文章我们再来回顾一下相关知识点。为什么要对一元函数的极值问题进行回顾?因为后面我会出一篇非线性规划问题的极值问题,其中会涉及到多元函…

【视觉算法系列1】使用 KerasCV YOLOv8 进行红绿灯检测(下)

提示:免费获取本文涉及的完整代码与数据集,请联系助理老师peaeci122 使用最新“KerasCV YOLOv8”模型进行红绿灯检测的综合指南 YOLO目标检测模型已经进入了无数的应用领域,从监控系统到自动驾驶汽车。那么,如果在KerasCV框架下…

4.DApp-MetaMask怎么连接本地Ganache

题记 用metamask连接本地ganache,以下是全部操作流程 下载Ganache ganache是一个以太坊的个人开发环境,可以在上面部署合约、开发程序和进行测试。 ganache官网:Ganache - Truffle Suite 可以点击下面的按钮直接下载 ,下载速度…

怎样自动开始播放网页视频?

有些视频网站,网页打开后,并不会自动播放视频,需要人工点击视频或者播放器的播放按钮,才能进入视频播放状态。有没有办法一打开页面就自动播放视频呢?下面我们就来分析研究一下。 首先使用浏览器的开发者工具查看&am…

MybatisPlus多表关联分页返回结果异常

1. 按照该博客进行多表关联分页查询: https://blog.csdn.net/code_ang/article/details/116448694 2.在实际测试过程中,发现异常,分页返回的结果时而正确,时而错误。 count函数满足预期 count函数不满足预期 只是count了主表的…

pytorch 入门(二)

本文为🔗小白入门Pytorch内部限免文章 🍨 本文为🔗小白入门Pytorch中的学习记录博客🍦 参考文章:【小白入门Pytorch】教案二🍖 原作者:K同学啊 目录 一、神经网络的组成部分1. 神经元2. 神经网络…

热成像仪的工作原理及在工业设备状态监测中的应用

前面我们介绍过>>热分析技术在工业设备状态监测中的应用,下面我们将深入探讨热成像仪的工作原理及在工业设备状态监测中的应用。 近年来,热成像仪作为一种先进的检测工具,在工业设备状态监测领域得到了广泛的应用。热成像仪能够通过探测…

oauth2和knife4j结合

1.先说knife4j是个什么东西 他是swagger的升级版,在有swagger的调试功能以及接口描述的基础上,让人看着更加一目了然。 这次可能说的比较浅,主要是说怎么使用以及简单配置,还有我自己踩过的坑,因为这个东西我也第一次…

软件环境基础(ROS、CMake)

参考视频:【全】无人驾驶系列知识入门到提高 本文旨在对视频内容规划控制方面做一些学习记录,希望帮助有需要的人学习提高。不对处,望指正。 0 ROS介绍 ROS特点: 点对点设计(比如一个结点读取相机数据,传…

yolo配置(windows)

文章目录 一、下载Anaconda和pycharm1 、Anaconda官方下载地址:1.2 Anaconda 的安装 下载好之后双击打开可执行安装文件:1.3 进入到安装界面:1.4 这里建议两个都勾选(第一个选项是将 Anaconda 添加到环境变量中,不勾选…

火山引擎 ByteHouse:双十一即将到来,直播商家如何用数据“点播成金”?

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 “双十一”电商大促脚步渐近,各大平台的战火又将燃起。直播电商以低成本、高转化率等优势备受商家青睐。据智研咨询数据显示,2022 年我国直播…

iOS——JSONModel的使用与JSONModel的嵌套

什么是JSONModel JSONModel是一个解析JSON数据的开源库,可以将JSON数据直接解析成自定义的model 使用 JSONModel 非常简单,只需要将你的 model 类继承自 JSONModel ,而同时 model 中的属性名又恰巧可以和 JSON 数据中的 key 名字一样的话,那么非常恭喜你,你的工作…

10.16作业

头文件 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include<QDebug> #include<QIcon> #include<QPushButton> #include<QLineEdit> #include<QLabel> #include<QMovie> #include<QCheckBox> #include<QPa…

MyCAT:回顾当年的热潮,探寻这款备受欢迎的数据库中间件的核心特性

什么是 MyCAT &#xff1f; 根据 MyCAT 官网 - http://mycat.io/ 的描述可以知道&#xff0c; MyCAT 是如下的一个东东&#xff1a; 一个彻底开源的&#xff0c;面向企业应用开发的大数据库集支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL集群的企业级数据库…