vue2数据响应式原理(5) 通过重写函数实现数组响应式监听

news2024/12/24 2:41:58

其实 我们之前对数组的一个监听 还并不是很完美
我们打开案例 打开 output.js
更改代码如下

import { observe } from "./dataResp"
const output = () => {
    var obj = {
        data: {
            data: {
                map: {
                    dom: {
                        isgin: true
                    }
                },
                arg: 13
            },
            name: "小猫猫"
        },
        bool: [1,2,3,4]
    };
    observe(obj);
    obj.bool.push(7);
    document.getElementById("text").innerHTML = obj.data.name;
}

export default output

运行结果如下
在这里插入图片描述

很明显 我们数组并捕获不到 push方法 除了 push 很多数组方法都捕获不到

首先 我们来看几个方法
分别是
在这里插入图片描述
这几个方法执行 说明 当前数组被改写了内容

那么 我们可以去改写这七个方法 我们在案例 src目录下创建 Arrays.js 然后 大家先要知道 这些方法被定义在哪里?
Array.prototype
Array是数组类型的一个类对象 这些方法就定义在Array的原型链上
所以 大家才能通过 数组.这些方法 去调用他们 而我们要做的就是 重写这些方法 要做的就是 调用原来的方法 然后 在后面再去做自己需要做的响应式的事情

我们先在src下创建一个def.js
然后将之前写在dataResp.js中的def放进def.js来

export const def = function(obj,key,value,enumerable) {
    Object.defineProperty(obj,key,{
        value,
        enumerable,
        //true  设为可写
        writable: true,
        //true  设为可被删除
        configurable: true
    });
}

然后 将dataResp.js中的def方法干掉 然后 dataResp.js引入一下def.js的 def方法

import { def } from './def.js';

这个是我之前没想清楚 抱歉

然后 我们在Arrays.js中编写代码如下

import { def } from './def.js';

const arrayPrototype = Array.prototype;

export const arrayMethods = Object.create(arrayPrototype);

const redefineArrayMethod = [
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'sort',
    'reverse'
]

redefineArrayMethod.forEach(item =>{
    const backupFunction = arrayPrototype[item];
    def(arrayMethods,item,function(){
        backupFunction.apply(this, arguments);
        console.log('数组执行了',item,'操作,值被修改为',this);
    },false);
})

这里 我们先定义了redefineArrayMethod变量 他的值是一个数组 对应下面每一个字符串下标 都是这些改变数组结构的函数关键字

然后定义 arrayPrototype 存一下Array的 原型链 prototype 因为 这些函数就在上面

然后 创建arrayMethods 记录创建数组 并将arrayPrototype

最后 循环redefineArrayMethod 对应每一次下标循环 拿到都是一个数组方法关键字 第一次拿到’push’ 第二次’pop’

然后 我们的响应式代码就可以写在这里 首先 我们先

const backupFunction = arrayPrototype[item];

备份一下原来的方法 因为 你别重写之后 方法原有的逻辑没有了啊 是不是

你别说 push我监听一下 写完 push都加不进去东西了 那响应个啥 这BUG了啊

然后 我们调用def

第一个参数是 arrayMethods 就是被创建的对象 第二个 这里传的是 当前循环的内容 就是方法名数组下标 看着是第几次循环 第一次 push 第二次 pop 第三次 shift 依次类推

第四个参数 不用说 这东西你们肯定不希望他参与遍历吧 果断false
至于第三个 是他的值 我们要改写这个函数啊 就写了这个函数新的内容

backupFunction.apply(this, arguments);

先把我们备份的之前的函数内容执行了 就是 比如 push 我们先用执行参数帮他把push应该有的增加下标的逻辑执行了 this不用说 肯定要的 当前对象 然后arguments代表我们当前函数拿到的所有参数 全部给了backupFunction.apply当参数 就是保证参数不要少了

然后下面的代码 我们就捕获被改变的这个事情

然后 我们改写 dataResp.js中的Observer类代码如下

class Observer{
    constructor(value) {
        //相当于  给拿到的对象  其中的__ob__绑定 值为thsi,在类中用this 表示取实例本身给__ob__赋值  最后一个enumerable为false 表示属性不参与for遍历
        def(value,'__ob__',this,false);
        if(Array.isArray(value)){
            Object.setPrototypeOf(value, arrayMethods);
        }
        this.walk(value);
    }
    walk(value) {
        for(let key in value){
            defineReactive(value,key);
        }
    }
}

就是 监听到 如果是数字类型 调用一下 Object.setPrototypeOf 监听

然后 我们再次运行代码
在这里插入图片描述
可以看到 我们重写的方法 就起效了 push被成功捕获 并输出了语句
在这里插入图片描述

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

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

相关文章

【经验与Bug】tensorflow草记

文章目录 1 常用小知识2 Learn1) 疑惑未解2) 为何要有"bias"? 3 问题处理1) jupyter的环境指定目录运行jupyter 2) Keras版本3) 为什么accuracy为100%,迭代时参数还在更新? 1 常用小知识 conda activate tf 在anaconda prompt使用&…

Android studio 播放音频文件 播放语速

一、使用 public class MainActivity extends AppCompatActivity {private Hsvolume mHsVolume null;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mHsVolume new Hsvolume(th…

【YOLO系列】YOLOv1论文笔记

论文链接:[1506.02640] You Only Look Once: Unified, Real-Time Object Detection (arxiv.org) YOLO将目标检测看作回归问题,使用单个神经网络直接从完整图像上预测边界框和类别概率。(端到端:输入原始数据,输出的是最…

E5EAA HENF105240R1将用于工业生产过程的测量、控制和管理

​E5EAA HENF105240R1将用于工业生产过程的测量、控制和管理 工业控制计算机是工业自动化控制系统的核心设备 工业控制计算机是工业自动化设备和信息产业基础设备的核心。传统意义上,将用于工业生产过程的测量、控制和管理的计算机统称为工业控制计算机,…

SpringBoot整合WebSocket的两种方式及微服务网关Gateway配置

一、说明 项目中后台微服务需要向前端页面推送消息,因此不可避免的需要用到WebSocket技术。SpringBoot已经为WebSocket的集成提供了很多支持,只是WebSocket消息如何通过微服务网关Spring Cloud Gateway向外暴露接口,实际开发过程中遇到了很多…

【数据结构第四章】- 串的模式匹配算法(BF 算法和 KMP 算法/用 C 语言实现)

目录 一、前言 二、BF 算法 三、KMP 算法 3.2.1 - KMP 算法的原理 3.2.2 - KMP 算法的实现 3.2.3 - KMP 算法的优化 创作不易,可以点点赞,如果能关注一下博主就更好了~ 一、前言 子串的定位运算通常称为串的模式匹配或串匹配。此运算的应用非常广…

美国主机的带宽和网络速度究竟有多快?

在选择一个主机时,其带宽和网络速度是非常重要的考虑因素。而美国主机在带宽和网络速度方面有着明显的优势,成为了众多用户的首选。那么,美国主机的带宽和网络速度究竟有多快呢?本文将通过分析美国主机的网络基础设施和数据中心设施&#xf…

golang入门项目——打卡抽奖系统

功能介绍 用户加入群组之后,会在签到群组所设的签到地点进行签到和签退,并限制同一个设备只能签到一个用户,签到成功之后。会获取一定的限制在该群组使用的积分。该群组可以设置一些抽奖活动,用户可使用该群组内的积分来进行该群…

Python+mysql+php搭建另类免费代理池

文章目录 前言:思路:开干:php连接MySQL取ip和端口:效果图: 最后调用代理池:总结: 前言: 为什么说另类的,因为我完全是按照我自己的想法来的,比较鸡肋,但是能用&#xff…

短视频app开发:如何提高视频播放稳定性

简介 如今,短视频已经成为人们日常生活中不可或缺的一部分,而短视频app的开发也日益成为了人们热议的话题。在短视频app开发的过程中,如何提高视频播放稳定性是一个非常重要的问题。本文将从短视频源码角度出发,分享提高短视频ap…

如何优化语音交友app开发的搜索和匹配算法

语音交友app开发的挑战 在当今社交媒体行业中,语音交友app开发已经成为一个热门的领域。越来越多的人开始使用语音交友app来寻找新的朋友,这也为开发者们带来了许多机会。然而,这个领域也面临着一些挑战。其中一个最大的挑战是如何优化搜索和…

掏空腰包,日子难过,机缘转岗软件测试,这100个日夜的心酸只有自己知道...

我今年27岁,原本从事着土木工程相关的工作,19年开始有了转行的想法... 大学刚毕业那年,我由于学的是土木工程专业,自然而然的从事了和土木工程相关的工作,房贷、车贷,在经济的高压下,当代社会许…

大数据题目测试(一)

目录 一、环境要求 二、提交结果要求 三、数据描述 四、功能要求 1.数据准备 2.使用 Spark,加载 HDFS 文件系统 meituan_waimai_meishi.csv 文件,并分别使用 RDD和 Spark SQL 完成以下分析(不用考虑数据去重)。 (1)配置环境…

Java设计模式-day01

1,设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中,而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大(Christopher Alexand…

React Native iOS打包详细步骤

一、在自己项目的iOS文件夹下新建一个文件夹取名bundle 二、将打包命令写到项目package.json文件里,终端执行 npm run bundle-ios 先添加如下(注意:这里写的路径"./ios/bundle"就是上面bundle创建的文件夹)&#xff1a…

C51单片机介绍

本文为学习51单片机的学习的基础,先介绍单片机是什么。所使用的单片机有什么资源。每一个功能的作用是什么。本文使用的是STC89C52RC 40I-PDIO40,故以此为基础研究学习。 C51单片机介绍 单片机的概述单片机的组成部分中央处理器程序存储器数据存储器定时…

图神经网络能做什么?

从概念上讲,我们可以将图神经网络的基本学习任务分为 5 个不同的方向: (1)图神 经网络方法; (2)图神经网络的理论理解; (3)图神经网络的可扩展性&#xff1b…

Git的进阶使用(二)

本篇文章旨在分享本人在学习Git时的随笔记🤩 文章目录 概述1、Git 分支1.1 主干分支1.2 其他分支1.2.1 创建分支1.2.2 查看分支1.2.3 切换分支1.2.4 删除分支 2、Git 合并2.1 主干分支2.2 其他分支2.3 合并分支 3、Git 冲突3.1 主干分支3.2 其他分支3.3 切换分支 -B…

Replika:AI智能聊天机器人

【产品介绍】 Replika,这个名字可能有点拗口,但如果你知道这是复制品Replica的同音变体,你即刻能明白这个产品的定位了。官方Luka公司定义它是你的AI朋友,默默学习你,最终成为你的复制品。它不像现在市面上各大厂的AI助…

《ChatGPT开发应用指南》,Datawhale开源了!

Datawhale发布 开源教程:HuggingLLM,Datawhale团队 随着ChatGPT的爆火,我们相信未来会有越来越多的大模型及类似OpenAI提供的服务出现,AI 正在逐渐平民化,将来每个人都可以利用大模型轻松地做出自己的AI产品。 Huggin…