vue2.0中如何实现数据监听
vue2中实现数据监听的原理
在Vue 2中,数据监听是通过ES5的Object.defineProperty实现的。Vue在初始化数据对象时,会遍历data对象,并使用Object.defineProperty为每个属性设置getter和setter。当你尝试读取或修改数据属性时,这些getter和setter会被触发,从而Vue能够追踪依赖并在数据变化时执行相应的更新操作。
Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法: Object.defineProperty(obj, prop, descriptor)
obj 要定义属性的对象。
prop 要定义或修改的属性的名称
descriptor 要定义或修改的属性描述符
属性描述符
-
value:默认值为undefined, 为对象的属性赋值
-
configurable:默认值为 false, 控制属性是否可以从对象中删除以及其特性(除了 value 和 writable)是否可以更改。
-
enumerable:默认值为 false,控制属性是否可以被遍历
-
writable:默认值为 false,控制属性是被可以被修改
-
存取器属性:属性描述符中如果配置了 get 和 set 中的任何一个,则该属性不再是一个普通属性,而变成了存取器属性。
get()读值函数:如果一个属性是存取器属性,则读取该属性时,会运行 get 方法,并将 get 方法得到的返回值作为属性值
set(newVal)存值函数:如果给该属性赋值,则会运行 set 方法,newVal 参数为赋值的值。
Vue2 数据响应式就是使用了这一点,在 getter 和 setter 函数中进行了数据绑定与派发更新。
注意点:value 和 writable 属性不能与 get 和 set 属性二者不可共存,二者只能选其一。
通过例子来看Object.defineProperty如何监听数据的变化?
let obj = {name: 'mike',like: ['football', 'baskball'],score: {js: 88, php:92}
}
function defineProp(obj, key, value){Object.defineProperty(obj, key, {configurable: true,enumerable: true,get(){console.log('getter doing')return value;},set(newVal){console.log('setter doing')value = newVal}})
}
function mapFn(){Object.keys(obj).forEach(key => defineProp(obj, key, obj[key]));
}
mapFn()
obj.name
//getter doing
// ‘mike’
obj.name = 'lili'
//setter doing
obj.name
//getter doing
// 'lili'
我们举例存取的数据都是基本类型,那如果是引用类型呢?
先来看看对象的存取吧
obj.score
// getter doing
// {js: 88, php: 92}
obj.score.js = 100
//getter doing
//100
注意: 从上面可以看到
- 获取score可以得到对应的对象数据
- 但是我们接着又给score的js属性重新赋值,但是通过打印的信息可以看出,设置新值的时候并没有进入到setter方法,也就意味着这个score上的js属性监听不到的
- 所以当给已被监听的对象属性赋值的时候,我们需要重新给这个新的属性添加存取器属性
现在我们来改造一下上面的代码吧,
- 将上面mapFn方法添加一个参数,参数为要监听的对象,如果这个参数为对象类型,那么为这个对象添加存取器属性.
let obj = {name: 'mike',like: ['football', 'baskball'],score: {js: 88, php:92}
}
function defineProp(obj, key, value){Object.defineProperty(obj, key, {configurable: true,enumerable: true,get(){console.log('getter doing')return value;},set(newVal){console.log('setter doing')value = newVal}})
}
function mapFn(obj){if(typeof obj !== 'object' || obj == null) return;Object.keys(obj).forEach(key => {defineProp(obj, key, obj[key]);if(typeof obj[key] === 'object' && obj[key] !== null) mapFn(obj[key]);});
}
mapFn(obj);
obj.score.js
//getter doing
//getter doing
//88
obj.score.js = 100
//getter doing
//setter doing
//100
可以看到上面对obj.score.js的复制第二次打印了“setter doing”
说明我们同时监听到了对象属性是对象的情况下的值
这里需要注意我们只能监听到obj初始化时候存在的属性哈,后期新增的属性,因为开始的时候我们并没有执行mapFn()方法,所以,后期新增的属性是监听不到的哈~
在vue2.0中好多人也会遇到这个问题,解决的办法是通过$set去解决,我们在这里不做赘述,只是提一下,让大家明白为什么会有这个问题
下面再来看
obj.like
// getter doing
//['football', 'baskball']
obj.like.push('swimming')
//getter doing
//3
我们看到虽然数组也是对象类型,但是,当我们给数组新增数据的时候,并没有进入到setter方法中,所以我们需要针对数组类型特殊处理,这里我们需要给对象的数组处理方法重新定义一下
现在来改造代码
let obj = {name: 'mike',like: ['football', 'baskball'],score: {js: 88, php:92}
}
//重新定义数组处理方法,添加监听
function reWriteArrayFn(obj){const arrayFn = ['push','pop','shift','unshift','splice','sort','reverse'];arrayFn.forEach(method => {obj[method] = function(){Array.prototype[method].apply(obj, arguments);console.log('watch array');}})
}
function defineProp(obj, key, value){Object.defineProperty(obj, key, {configurable: true,enumerable: true,get(){console.log('getter doing')return value;},set(newVal){console.log('setter doing')value = newVal}})
}
function mapFn(obj){if(typeof obj !== 'object' || obj == null) return;Object.keys(obj).forEach(key => {defineProp(obj, key, obj[key]);if(typeof obj[key] === 'object' && obj[key] !== null) {if(Array.isArray(obj[key])){reWriteArrayFn(obj[key]);} else {mapFn(obj[key]);}};});
}
mapFn(obj)
obj.like
//getter doing
//['football', 'baskball', push: ƒ, pop: ƒ, shift: ƒ, unshift: ƒ, splice: ƒ, …]
obj.like.push('swimming')
//getter doing
//watch array
//undefined. 这里我们忘记添加返回了,应该有个return true的
obj.like
//getter doing
//['football', 'baskball', "swimming",push: ƒ, pop: ƒ, shift: ƒ, unshift: ƒ, splice: ƒ, …]
这样,我们就清楚了vue2.0对象监听的原理了,可以看出,我们需要对对象数据的每一个属性都添加存取器属性,遇到数组类型还要重新给数据方法做重写操作,那么,我们可以想象,如果这个对象在十分复杂的情况下,是不是实现起来非常复杂,而且对性能的消耗也是非常的巨大
所以,vue在3.0升级了监听数据的实现实行,用proxy来代替了Object.defineProperty,在下一篇文章中我们来讨论.
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
vue2.0中如何实现数据监听
vue2中实现数据监听的原理 在Vue 2中,数据监听是通过ES5的Object.defineProperty实现的。Vue在初始化数据对象时,会遍历data对象,并使用Object.defineProperty为每个属性设置getter和setter。当你尝试读取或修改数据属性时,这些g…...
![](https://i-blog.csdnimg.cn/direct/350ad0f9ec4b476ba689d25dd6c8d8d0.png)
kafka开启kerberos和ACL
作者:恩慈 一、部署kafka-KB包 1.上传软件包 依次点击 部署中心----部署组件----上传软件包 选择需要升级的kafka版本并点击确定 2.部署kafka 依次点击部署中心----部署组件----物理/虚拟机部署----选择集群----下一步 选择手动部署-…...
![](https://www.ngui.cc/images/no-images.jpg)
QT+winodow 代码适配调试总结(三)
问题描述: 1、开发测试环境为: A: window10 64位 B: QT版本为4.8.6 C:采用VS2017 C++ Compiler 9.0 (x86)编译器版本 根据总结(二)经验,开发环境的可执行程序显示正常; 2、新的环境运行的时候显示乱码; 经过查阅资料,还是代码环境编码配置的问题,下面为解…...
![](https://img-blog.csdnimg.cn/direct/ee192b61bd234c87be9d198fb540140e.png)
Linux之旅:常用的指令,热键和权限管理
目录 前言 1. Linux指令 (1) ls (2) pwd 和 cd (3)touch 和 mkdir (4) rmdir 和 rm (5)cp (6)mv (7)…...
![](https://i-blog.csdnimg.cn/direct/cb648490fefe4b71b37e76a753ccf95f.png)
简单实用的企业舆情安全解决方案
前言:企业舆情安全重要吗?其实很重要,尤其面对负面新闻,主动处理和应对,可以掌握主动权,避免股价下跌等,那么如何做使用简单实用的企业舆情解决方案呢? 背景 好了,提取词…...
![](https://i-blog.csdnimg.cn/direct/e9f8b34679004312aba1d7640017d697.png)
【中项】系统集成项目管理工程师-第2章 信息技术发展-2.1信息技术及其发展-2.1.1计算机软硬件与2.1.2计算机网络
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...
![](https://www.ngui.cc/images/no-images.jpg)
SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 前言 …...
![](https://www.ngui.cc/images/no-images.jpg)
ubuntu 上安装中文输入法
在Ubuntu上安装中文输入法,通常有以下几种方法: 方法一:使用Fcitx输入法框架和搜狗输入法 安装Fcitx: sudo apt update sudo apt install fcitx fcitx-bin fcitx-table-all 安装搜狗输入法: 首先,从搜狗…...
![](https://i-blog.csdnimg.cn/direct/1cc472e7a03145589f8bf8269baa4cdf.png)
Postman导出excel文件
0 写在前面 在我们后端写接口的时候,前端页面还没有出来,我们就得先接口测试,在此记录下如何使用postman测试导出excel接口。 如果不会使用接口传参可以看我这篇博客如何使用Postman 1 方法一 2 方法二 3 写在末尾 虽然在代码中写入文件名…...
![](https://img-blog.csdnimg.cn/img_convert/df20eecb5aab870ca9877a3c3f344176.png)
你还在手动构建Python项目吗?PyBuilder让一切自动化!
在 Python 项目开发中,构建和管理项目是一项繁琐但必不可少的工作。你可能需要处理依赖项、运行测试、生成文档等。这时候,PyBuilder 出场了。它是一个强大的构建自动化工具,可以帮助你简化项目管理,让你更专注于编写代码。 什么…...
![](https://i-blog.csdnimg.cn/direct/7036e979c8fd4bc999aa506260a039af.png)
WebRTC音视频-前言介绍
目录 效果预期 1:WebRTC相关简介 1.1:WebRTC和RTC 1.2:WebRTC前景和应用 2:WebRTC通话原理 2.1:媒体协商 2.2:网络协商 2.3:信令服务器 效果预期 1:WebRTC相关简介 1.1&…...
![](https://www.ngui.cc/images/no-images.jpg)
centos/rocky容器中安装xfce、xrdp记录
最近需要一台机器来测试rdp连接,使用容器linuxxfcexrdp来实现,在此记录下主要步骤 启动rockylinux容器(其他linux发行版步骤应该相似) docker run -it -p 33891:3389 rockylinux:9.3 bash容器内操作 # 省略替换软件源步骤 ...# …...
![](https://img-blog.csdnimg.cn/img_convert/e4ebba6b3079ed7a2aaf156241cfd5d9.png)
实战:Eureka的概念作用以及用法详解
概叙 什么是Eureka? Netflix Eureka 是一款由 Netflix 开源的基于 REST 服务的注册中心,用于提供服务发现功能。Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 进行了二次封装,主要负责…...
![](https://i-blog.csdnimg.cn/direct/e265fafb13af4e67a3fc6d5adf9cea18.jpeg)
jupyter_contrib_nbextensions安装失败问题
目录 1.文件路径长度问题 2.jupyter不出现Nbextensions选项 1.文件路径长度问题 问题: could not create build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item\contrib_nbextensions_help_item.yaml: No su…...
![](https://img-blog.csdnimg.cn/img_convert/ef8fd1b0cf505c7d4f91432ca56f119a.png)
设计模式-Git-其他
目录 设计模式? 创建型模式 单例模式? 啥情况需要单例模式 实现单例模式的关键点? 常见的单例模式实现? 01、饿汉式如何实现单例? 02、懒汉式如何实现单例? 03、双重检查锁定如何实现单例ÿ…...
![](https://i-blog.csdnimg.cn/direct/6af594287d3649baa8746d1254c040a5.png)
【C#】计算两条直线的交点坐标
问题描述 计算两条直线的交点坐标,可以理解为给定坐标P1、P2、P3、P4,形成两条线,返回这两条直线的交点坐标? 注意区分:这两条线是否垂直、是否平行。 代码实现 斜率解释 斜率是数学中的一个概念,特别是…...
![](https://i-blog.csdnimg.cn/direct/342412485f9f4f2da4128b517472ccd0.png)
在项目服务器部署git 并实现自动提交
以下场景适合在服务器当中使用git 方便提交代码,同时不需要外部的git仓库(码云gitee或者github作为管理平台)。依靠服务器本身ssh 连接协议做为git提交的地址,同时利用钩子自动同步项目代码 首先下载git sudo apt update sudo a…...
![](https://www.ngui.cc/images/no-images.jpg)
前缀匹配工具之IP-Prefix
目录 基本概念: 技术背景: 用户需求: 安全需求: 企业内部的访问控制需求: IP-Prefix的配置与语句分析: 调用方式: 尾声 基本概念: IP-Prefix,即IP前缀,相比传统ACL,它能…...
![](https://www.ngui.cc/images/no-images.jpg)
等级保护测评案例分享及合规建议
一、黑龙江省等级保护测评概述 黑龙江省等级保护测评(简称“等保测评”)是依据国家网络安全等级保护制度的要求,对信息系统进行安全等级划分和安全保护能力的评估。等保测评不仅能够帮助企业和组织发现潜在的安全风险,还能够指导…...
![](https://i-blog.csdnimg.cn/direct/bba848a76d21448ca0ba37a219b2a305.png)
GOLLIE : ANNOTATION GUIDELINES IMPROVE ZERO-SHOT INFORMATION-EXTRACTION
文章目录 题目摘要引言方法实验消融研究 题目 Techgpt-2.0:解决知识图谱构建任务的大型语言模型项目 论文地址:https://arxiv.org/abs/2310.03668 摘要 大型语言模型 (LLM) 与指令调优相结合,在泛化到未见过的任务时取得了重大进展。然而,它…...
![](https://img-blog.csdnimg.cn/img_convert/d31dabad869688a0ab011883fb7573db.png#pic_center)
2024-07-19 Unity插件 Odin Inspector9 —— Validation Attributes
文章目录 1 说明2 验证特性2.1 AssetsOnly / SceneObjectsOnly2.2 ChildGameObjectsOnly2.3 DisallowModificationsIn2.4 FilePath2.5 FolderPath2.6 MaxValue / MinValue2.7 MinMaxSlider2.8 PropertyRange2.9 Required2.10 RequiredIn2.11 RequiredListLength2.12 ValidateIn…...
![](https://i-blog.csdnimg.cn/direct/c1411a0851794086b9710d8beac6dd3b.png)
跨平台WPF音乐商店应用程序
目录 一 简介 二 设计思路 三 源码 一 简介 支持在线检索音乐,支持实时浏览当前收藏的音乐及音乐数据的持久化。 二 设计思路 采用MVVM架构,前后端分离,子界面弹出始终位于主界面的中心。 三 源码 视窗引导启动源码: namesp…...
![](https://www.ngui.cc/images/no-images.jpg)
设计模式简述(一)
定义:设计模式指的是在软件开发过程中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案。创建型设计模式关注对象的创建过程,提供了更灵活、可扩展的对象创建机制。结构型设计模式用于解决…...
![](https://www.ngui.cc/images/no-images.jpg)
OSI参考模型:解析网络通信的七层框架
引言 在现代计算机网络中,OSI(开放式系统互联)参考模型是理解和设计网络通信协议的基础。1978年由国际标准化组织(ISO)提出,OSI模型定义了网络通信的七层结构,每一层都承担着特定的功能&#x…...
![](https://i-blog.csdnimg.cn/direct/c8b21d5996e14ef7bf8e2a85c6c4a5d2.png)
QT通用配置文件库(QPreferences)
QT通用配置文件库(QPreferences) QPreferences项目是基于nlohmann/json的qt可视化配置文件库,将配置保存成json格式,并提供UI查看与修改,可通过cmake可快速添加进项目。默认支持基本类型、stl常用容器、基本类型与stl容器组成的结构体&#…...
![](https://i-blog.csdnimg.cn/direct/187813a2e202437886f69159090f4404.png)
如何搭建一个RADIUS服务器?
1. 系统环境 1.1.操作系统 Ubuntu-20.04.1 (kernel: 5.15.0-58-generic) 1.2.所需软件 FreeRADIUS MariaDB 1.3.注意事项 本文提到的所有操作,都是以root 身份执行; 2. FreeRADIUS的安装 2.1. 安装FreeRADIUS服务器程序 以…...
![](https://i-blog.csdnimg.cn/direct/728bd47bb9554c0ca4965c1d48a6dada.png)
双机热备综合实验
1,对现有网络进行改造升级,将当个防火墙组网改成双机热备的组网形式,做负载分担模式,游客区和DMZ区走FW3,生产区和办公区的流量走FW1 2,办公区上网用户限制流量不超过100M,其中销售部人员在其基…...
![](https://www.ngui.cc/images/no-images.jpg)
Java和Python的图结构如何实现图的深度优先搜索算法
Java和Python的图结构如何实现图的深度优先搜索算法? 在Java和Python中,实现深度优先搜索(DFS)算法的基本思路都是通过递归或栈来探索图的各个节点。 Java实现DFS:Java import java.util.ArrayList; import java.uti…...
![](https://www.ngui.cc/images/no-images.jpg)
Web学习day05
html&css 目录 html&css 文章目录 一、web开发 1.1工作流程 1.2开发技术 二、HTML 2.1HTML规范 2.2基础标签 2.2.1标题 2.2.2水平线 2.2.3段落和换行 2.2.4文字效果 2.2.5超链接 2.2.6图像 2.2.7音频和视频 三、布局标签 3.1列表 3.2容器 3.3表格 3…...
![](https://i-blog.csdnimg.cn/direct/1d844b8e6917460d92e405b4a8036267.png)
LINUX客户端client(socket、connect)实现客户端发送,服务器接收
SERVICE端见前一篇文章 5. 客户端连接函数 connect()(与前面的bind一样) int connect (int sockfd, struct sockaddr * serv_addr, int addrlen) 参数: sockfd: 通过 socket() 函数拿到的 fd addr:struct sockaddr 的结构体变量地址 addr…...
![](http://img.iplaysoft.com/wp-content/uploads/2008/attachments/month_0606/t200668153754.jpg)
网站代码优化多少钱/天津网站推广
摘自:http://www.iplaysoft.com/robocode.html Robocode(用游戏来学习Java技术还是用Java来玩游戏?)用你的JAVA编程技术来玩游戏吧!不会JAVA?那就用游戏来学习JAVA吧!什么是Robocode? 其实我对机器人一直很感兴趣。我…...
![](https://images2015.cnblogs.com/blog/576966/201602/576966-20160204172055132-1931391643.png)
西昌市做网站的公司/平台推广引流怎么做
1.构建本地拓展的ActionScript库时候要注意SWF文件的版本兼容性: 参考:http://help.adobe.com/zh_CN/air/extensions/WS99209310cacd98cc2d13931c1300f2c84c7-8000.html 2.使用Flash Builder导出用于发行的APk包: 参考:http://hel…...
![](/images/no-images.jpg)
做网站设计软件/百度推广代运营公司
原理 工作过程 主机A的IP地址为:192.168.1.1 MAC地址为:0A-11-22-33-44-01;主机B的IP地址为:192.168.1.2 MAC地址为:0A-11-22-33-44-02;当主机A要与主机B通信时,地址解析协议可以将主机B的IP地…...
![](https://static.leiphone.com/uploads/new/article/740_740/201803/5aa721fcd910d.png?imageMogr2/format/jpg/quality/90)
成都公司网页制作/seo高级优化技巧
https://www.leiphone.com/news/201803/Tw0nrq6vGDIvbmXr.html 雷锋网(公众号:雷锋网)获悉,3月13日,东芝发布新AR眼镜dynaEdge AR,其由一个单臂眼镜和一个分离的计算单元组成。眼镜售价1899美元,面向企业级用户。 当所…...
![](/images/no-images.jpg)
icp网站 是什么意思/网站排名前十
Beego是一个完全的MVC框架,你可以使用你的Go语言专业技术构建你的web应用程序。Beego框架下,你可以自动化地实现测试、打包和部署。Revel能让Go语言的web开发如虎添翼,大大提高你的开发效率。 Martini是一个受到Sinatra (一个Ruby 框架)启发而…...
![](/images/no-images.jpg)
wordpress高亮代码/seo内部优化具体做什么
自定义的DataSet要加 [Serializable]标记。...