第9集丨Vue 江湖 —— 监测数据原理
目录
- 一、修改数据时的一个问题
- 1.1 现象一
- 1.2 现象二
- 二、Vue监测数据原理
- 2.1 模拟一个数据监测
- 2.2 数据劫持
- 2.3 Vue.set()/vm.$set()
- 2.4 基本原理
- 2.4.1 如何监测对象中的数据?
- 2.4.2 如何监测数组中的数据?
- 2.4.3 修改数组中的某个元素
- 2.5 案例
- 2.5.1 需求功能
- 2.5.2 实现
一、修改数据时的一个问题
下面案例中,我们定义了一个按钮,期望是:点击按钮更新persons[0]
的信息。
但实际问题是:Vue
监测不到数据的变化。
<div id="root"><h2>列表过滤</h2><button @click="change">更新令狐冲信息</button><ul><li v-for="(p,index) in persons" :key="p.id" >{{p.name}} - {{p.use}} - {{p.age}}</li></ul></div>
<script>const vm = new Vue({el:'#root',data:{persons:[{id:'001',name:'令狐冲',use:"独孤九剑",sex:'男',age:20},{id:'002',name:'任盈盈',use:"仙女下凡",sex:'女',age:19},{id:'003',name:'任我行',use:"吸星大法",sex:'男',age:50}]},methods: {change(){// 可行的方式// this.persons[0].name = "假的令狐冲";// this.persons[0].use = "葵花宝典";// this.persons[0].age = 100;// Vue没发现你修改了数据,其实已经改了this.persons[0] = {id:'001',name:'假的令狐冲',use:"葵花宝典",sex:'男',age:100}}},})
</script>
1.1 现象一
- 在浏览器中打开页面,在打开
vue-devtools
- 点击按钮
- 观察工具中的数据,
竟然没有发生变化!!!
但其实数据已经真实改变了 - 我们可以通过控制台,输入
vm.persons[0]
查看,发现数据确实变了。
1.2 现象二
- 在浏览器中打开页面,然后先点击按钮
- 再打开
vue-devtools
- 查看工具中数据,发现
数据改变了!!!
二、Vue监测数据原理
2.1 模拟一个数据监测
下面案例中,当data
的数据发生变化,就会在控制台打印出一句话。
let data = {name:'令狐冲',menpai:'华山派'
}// 创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data)// 准备一个vm的实例对象
let vm = {}
vm._data = data = obs;function Observer (obj) {// 汇总对象中所有的属性形成一个数组const keys = Object.keys(obj);keys.forEach((k)=>{Object.defineProperty(this,k,{get(){return obj[k]},set(val){console.log(`${k}被改了,之后解析模板,生成虚拟DOM....`);obj[k] = val}})})
}
2.2 数据劫持
数据劫持
:在访问或修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作,如修改返回结果。
Vue 2.x
使用的是 Object.defineProperty()
,而 Vue
在 3.x
版本之后改用 Proxy
进行实现
2.3 Vue.set()/vm.$set()
-
语法:Vue.set(
target
,propertyName/index
,value
) -
功能:向
响应式对象
中添加一个property
,并确保这个新property
同样是响应式
的,且触发视图更新
。 -
注意:它必须用于向
响应式对象上
添加新 property
,因为 Vue无法探测普通的新增 property (比如this.myObject.newProperty = 'hi'
)
Vue.set(this.person.hobby, 0, "哈哈哈")this.$set(this.person.hobby, 0, "哈哈哈")// 从第0个位置,删一个,在插入一个
// this.person.hobby.splice(0,1,"哈哈哈")
2.4 基本原理
Vue
监测到data
中的数据(所有层次的数据
)发生变化,就会调用setter
重新解析模板,解析引用的到的数据的值。
2.4.1 如何监测对象中的数据?
-
通过
setter
实现监视,且要在new Vue
时就传入要监测的数据。(1). 对象中
后追加的属性
,Vue默认不做响应式处理
(2). 如需给后添加的属性
做响应式,请使用如下API
:Vue.set(target, propertyName/index,value)vm.$set(target, propertyName/index,value)
2.4.2 如何监测数组中的数据?
Vue
通过包裹数组的更新元素的方法
实现,本质就是做了两件事:
- (1). 调用原生对应的方法对数组进行更新。
- (2). 重新解析模板,进而更新页面。
数组中这些被包裹过的方法
包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
2.4.3 修改数组中的某个元素
在Vue
中,修改数组中的某个元素一定要用如下方法,才能实现响应式:
被包裹过的方法
:push()、pop()、shift()、unshift()、splice()、sort(). reverse()- 通过
Vue.set()
或vm.$set()
注意:Vue.set()
和 vm.$set()
不能给vm
或 vm的根数据对象(vm.data)
添加属性。
2.5 案例
2.5.1 需求功能
- 需求如下截图
2.5.2 实现
<div id="root"><h2>笑傲江湖</h2><hr><div><button @click="person.age++">年龄+1岁</button> <button @click="addSex">添加性别属性,默认值:男</button> <button @click="addFriend">在列表首位添加一个朋友</button><button @click="updateFName">修改第一个朋友的名字为:小三</button><button @click="addHobby">添加一个爱好</button><button @click="updateHobby">修改第一个爱好为: 哈哈哈</button><button @click="removeHobby">过滤爱好中的喝酒</button></div><h3>姓名:{{person.name}}</h3><h3>年龄:{{person.age}}</h3><h3 v-if="person.sex">性别:{{person.sex}}</h3><h3>爱好:</h3><ul><li v-for="(h,index) in person.hobby" ::key="index">{{h}}</li></ul><h3>朋友:</h3><ul><li v-for="(f,index) in person.friends" ::key="index">{{f.name}} - {{f.age}}</li></ul></div>
<script>const vm = new Vue({el:'#root',data:{person:{name:'令狐冲',age:26,hobby:['喝酒','练剑','行侠仗义'],friends:[{name:'田伯光',age:30},{name:'任我行',age:50}]}},methods: {addSex(){// Vue.set(this.person,'sex','男')this.$set(this.person,'sex','男')},addFriend(){this.person.friends.unshift({name:'任盈盈',age:'26'})},updateFName(){this.person.friends[0].name = '小三'},addHobby(){this.person.hobby.push('大笑')},updateHobby(){// 从第0个位置,删一个,在插入一个// this.person.hobby.splice(0,1,"哈哈哈")// Vue.set(this.person.hobby, 0, "哈哈哈")this.$set(this.person.hobby, 0, "哈哈哈")},removeHobby(){this.person.hobby = this.person.hobby.filter((h)=>{return h !== "喝酒"})}},})
</script>
相关文章:

第9集丨Vue 江湖 —— 监测数据原理
目录 一、修改数据时的一个问题1.1 现象一1.2 现象二 二、Vue监测数据原理2.1 模拟一个数据监测2.2 数据劫持2.3 Vue.set()/vm.$set()2.4 基本原理2.4.1 如何监测对象中的数据?2.4.2 如何监测数组中的数据?2.4.3 修改数组中的某个元素 2.5 案例2.5.1 需求功能2.5.2 实现 一、…...
【YOLO】替换骨干网络为轻量级网络MobileNet3
替换骨干网络为轻量级网络MobileNet_v3 上一章 模型网络结构解析&增加小目标检测 文章目录 替换骨干网络为轻量级网络MobileNet_v3前言一、MobileNetV3介绍二、MobileNetV2&MobileNetV3三、MobileNetV3网络结构1. 结构查看2. 查看每层featuremap大小三、YOLOV5替换骨干…...

如何识别手机是否有灵动岛(dynamic island)
如何识别手机是否有灵动岛(dynamic island) 灵动岛是苹果2022年9月推出的iPhone 14 Pro、iPhone 14 Pro Max首次出现,操作系统最低是iOS16.0。带灵动岛的手机在竖屏时顶部工具栏大于等于51像素。 #define isHaveDynamicIsland ({ BOOL isH…...
Linux设备树简介
一、起源 减少垃圾代码 减轻驱动开发工作量 驱动代码和设备信息分离 参考Open Fireware设计 用来记录硬件平台中各种硬件设备的属性信息 二、基本组成 两种源文件: xxxxx.dts dts是device tree source的缩写 xxxxx.dtsi dtsi是device tree source include的…...

Ubuntu类IOS主题设置
1.依次执行下面三条命令: sudo apt install gnome-shell-extensions sudo apt install gnome-tweak-tool sudo apt install chrome-gnome-shell2.下载主题,也是命令: git clone <https://github.com/qingchendelaike/GNOME-OSX-II-Theme…...

RabbitMQ学习——发布订阅/fanout模式 topic模式 rabbitmq回调确认 延迟队列(死信)设计
目录 引出点对点(simple)Work queues 一对多发布订阅/fanout模式以登陆验证码为例pom文件导包application.yml文件rabbitmq的配置生产者生成验证码,发送给交换机消费者消费验证码 topic模式配置类增加配置生产者发送信息进行发送控制台查看 rabbitmq回调确认配置类验…...

Leetcode算法递归类—合并两个有序链表
目录 21. 合并两个有序链表 题解: 代码: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2&a…...

YOLOv5可视化界面
Pyside6可视化界面 安装Pyside6 激活之前的虚拟环境yolov5 在该环境的终端输入以下命令 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyside6输入where python找到当前使用的Python的路径 找到该路径下的designer.exe文件(/Lib/site-packages/PySi…...
C语言使用库函数实现大小写字母转换
功能;多行输入,输入大写字母,返回相应的小写字母;输入小写字母,返回相应的大写字母 需要用到的库函数: islower() -- 判断是否为小写,是,返回非0,…...

Redis简单学习
Redis是一个基于内存的key-value结构数据库 linux上面安装: Redis存储的是key-value结构的数据,其中key是字符串,value有常见的5中数据类型: 字符串 string哈希 hash列表 list集合 set有序集合 sorted set 字符串常用操作&am…...

《Python入门到精通》函数详解
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 函数 1、函数的调用2、函数的参数2.1、变量的就近原则2.2、传递参数2.3、形参和实…...

PHP流浪动物招领网站mysql数据库web结构apache计算机软件工程网页wamp
一、源码特点 PHP流浪动物招领网站 是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 下载链接 nullhttps://download.csdn.net/download/qq_41221322/88190168视频演示 …...
android—ktor-client封装使用,请求网络
ktor-client封装使用步骤: 1.导入依赖: 设置版本号: buildscript {ext.ktor_version 2.3.1 }添加依赖: implementation "io.ktor:ktor-client-okhttp:$ktor_version"implementation "io.ktor:ktor-client-auth…...

GD32F103VE侵入事件
GD32F103VE的TAMPER引脚(PC13),当PC13输入低电平时,会产生一个侵入检测事件。它会将所有“数据备份寄存器”内容清除。 这个功能有什么用? 一是防止被人开壳,抄袭。二是自毁功能。 直奔主题,多一句就是浪费时间。测试…...

将tp5项目、fastadmin项目部署到服务器宝塔面板
目录 一、将你的fastadmin或者tp5项目文件夹上传至你的服务器域名根目录下 二、修改你的网站目录指向,指向public目录,点击保存,并取消勾选防跨站攻击。 三、配置伪静态 四、fastadmin框架上传至服务器后如果想要访问后台可以进行重定向&am…...

Jenkins+Docker+SpringCloud微服务持续集成
JenkinsDockerSpringCloud微服务持续集成 JenkinsDockerSpringCloud持续集成流程说明SpringCloud微服务源码概述本地运行微服务本地部署微服务 Docker安装和Dockerfile制作微服务镜像Harbor镜像仓库安装及使用在Harbor创建用户和项目上传镜像到Harbor从Harbor下载镜像 微服务持…...

系统架构设计师-系统可靠性分析与设计
目录 一、可靠性相关基本概念 二、可靠性指标 1、串联系统与并联系统可靠性指标计算 2、混合系统 三、可靠性设计 1、影响软件可靠性的主要因素: 2、增加可靠性的解决方案 2.1 避错技术 2.2 降低复杂度设计 2.3 检错技术 2.4 容错技术 3、双机容错 一、可靠性相关…...

Linux(CentOS7)搭建达梦数据库
参考官方文档 本文记录一下达梦数据库的安装步骤,在安装的过程中出现了一些问题,进行了处理。 文章目录 安装前准备数据库安装命令行安装图形化安装 配置实例注册服务启动、停止数据库达梦数据库卸载 安装前准备 用户在安装 DM 数据库之前需要检查或修…...
[杂谈]-国产MCU竞争力浅析
[杂谈]-国产MCU竞争力浅析 文章目录 [杂谈]-国产MCU竞争力浅析1、研发方面2、技术方面3、市场方面4、应用方面5、生态方面6、总结 微控制器(MCU)是一种集成了微处理器、存储器、输入/输出接口和其他外设的单片电路,广泛应用于各种电子产品和系…...
4.1、Flink任务怎样读取集合中的数据
1、API说明 非并行数据源: def fromElements[T: TypeInformation](data: T*): DataStream[T] def fromCollection[T: TypeInformation](data: Seq[T]): DataStream[T] def fromCollection[T: TypeInformation] (data: Iterator[T]): Data…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...