当前位置: 首页 > news >正文

第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 现象一

  1. 在浏览器中打开页面,在打开vue-devtools
  2. 点击按钮
  3. 观察工具中的数据,竟然没有发生变化!!!但其实数据已经真实改变了
  4. 我们可以通过控制台,输入vm.persons[0] 查看,发现数据确实变了。

在这里插入图片描述

1.2 现象二

  1. 在浏览器中打开页面,然后先点击按钮
  2. 再打开vue-devtools
  3. 查看工具中数据,发现数据改变了!!!

在这里插入图片描述

二、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(),而 Vue3.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() 不能给vmvm的根数据对象(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)

如何识别手机是否有灵动岛&#xff08;dynamic island&#xff09; 灵动岛是苹果2022年9月推出的iPhone 14 Pro、iPhone 14 Pro Max首次出现&#xff0c;操作系统最低是iOS16.0。带灵动岛的手机在竖屏时顶部工具栏大于等于51像素。 #define isHaveDynamicIsland ({ BOOL isH…...

Linux设备树简介

一、起源 减少垃圾代码 减轻驱动开发工作量 驱动代码和设备信息分离 参考Open Fireware设计 用来记录硬件平台中各种硬件设备的属性信息 二、基本组成 两种源文件&#xff1a; xxxxx.dts dts是device tree source的缩写 xxxxx.dtsi dtsi是device tree source include的…...

Ubuntu类IOS主题设置

1.依次执行下面三条命令&#xff1a; sudo apt install gnome-shell-extensions sudo apt install gnome-tweak-tool sudo apt install chrome-gnome-shell2.下载主题&#xff0c;也是命令&#xff1a; git clone <https://github.com/qingchendelaike/GNOME-OSX-II-Theme…...

RabbitMQ学习——发布订阅/fanout模式 topic模式 rabbitmq回调确认 延迟队列(死信)设计

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

Leetcode算法递归类—合并两个有序链表

目录 21. 合并两个有序链表 题解&#xff1a; 代码&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[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文件&#xff08;/Lib/site-packages/PySi…...

C语言使用库函数实现大小写字母转换

功能&#xff1b;多行输入&#xff0c;输入大写字母&#xff0c;返回相应的小写字母&#xff1b;输入小写字母&#xff0c;返回相应的大写字母 需要用到的库函数&#xff1a; islower&#xff08;&#xff09; -- 判断是否为小写&#xff0c;是&#xff0c;返回非0&#xff0c;…...

Redis简单学习

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

《Python入门到精通》函数详解

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

PHP流浪动物招领网站mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP流浪动物招领网站 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 下载链接 nullhttps://download.csdn.net/download/qq_41221322/88190168视频演示 …...

android—ktor-client封装使用,请求网络

ktor-client封装使用步骤&#xff1a; 1.导入依赖&#xff1a; 设置版本号&#xff1a; buildscript {ext.ktor_version 2.3.1 }添加依赖&#xff1a; implementation "io.ktor:ktor-client-okhttp:$ktor_version"implementation "io.ktor:ktor-client-auth…...

GD32F103VE侵入事件

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

将tp5项目、fastadmin项目部署到服务器宝塔面板

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

Jenkins+Docker+SpringCloud微服务持续集成

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

系统架构设计师-系统可靠性分析与设计

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

Linux(CentOS7)搭建达梦数据库

参考官方文档 本文记录一下达梦数据库的安装步骤&#xff0c;在安装的过程中出现了一些问题&#xff0c;进行了处理。 文章目录 安装前准备数据库安装命令行安装图形化安装 配置实例注册服务启动、停止数据库达梦数据库卸载 安装前准备 用户在安装 DM 数据库之前需要检查或修…...

[杂谈]-国产MCU竞争力浅析

[杂谈]-国产MCU竞争力浅析 文章目录 [杂谈]-国产MCU竞争力浅析1、研发方面2、技术方面3、市场方面4、应用方面5、生态方面6、总结 微控制器&#xff08;MCU&#xff09;是一种集成了微处理器、存储器、输入/输出接口和其他外设的单片电路&#xff0c;广泛应用于各种电子产品和系…...

4.1、Flink任务怎样读取集合中的数据

1、API说明 非并行数据源&#xff1a; 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…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...