vue2 数据响应式Object.defineProperty

news2024/11/25 2:30:10

我们通常可以对进行输入框进行数据的监听,只需要用到了input 事件或 change事件,就可以实时监听到数据的改变,但是如果只是一个单独的数据呢?怎么去做监听,watch吗??哈哈。

所以 vue响应式就用到了object.defineProperty 中的 get 和 set 方法 ,如果对方法不了解可访问蓝色文字。简单来说 只要一访问就会触发get,设置就会触发set。

基本语法:

Object.defineProperty(对象,键,{
        get (   )   {   },
        set (val) {   }        
})

 let data = {
     name:'奥特曼'
 }

 Object.defineProperty(data,'name',{
       get(){
         console.log('访问了')
       },
       set(val){
        console.log('设置了,值是:',val)
      }
  })

1. 单个数据实现响应

实现效果:

为了和vue保持格式一致 我们先定义初始变量data ,并且一开始把值赋给类名为name的内容数据

<div class="name"></div>
<script>
     let data = {
       name:'奥特曼'
    }

   function setName() {
       document.querySelector('.name').innerHTML = username
    }

    setName() 
 </script>

接下来要对data.name进行实时的监听,就要用到了obj.defineProperty

     let username = "奥特曼";
      Object.defineProperty(data, "name", {
        get() {
          console.log("访问了");
          return username;
        },
        set(val) {
          console.log("设置了,值是:", val);
          username = val;
          setName();
        },
      });

这里注意 特意用了一个中间变量 username,如果不这么用你可能会想到,错误写法别抄哦

      get(){
              console.log('访问了');
              return data.name
           },

为什么不直接把data.username给返回出去,为什么要返回一个值一样的username?原因就是 我们返回着data.name 其实也是在访问他,然后呢每次访问每次进入get函数 就会进入一个死循环。

2.多个数据实现响应式

这里就不过多解释了 只需要把对象循环一下 利用Object.defineProperty监听每个属性,我相信你可以看懂的

<script>    
    let data = {
        username:'奥特曼',
        age:18,
    }

    function setData() {
        username.innerHTML = data.username
        age.innerHTML = data.age
    }

    function observe(data) {
        for (const key in data) {
            let value = data[key]
            Object.defineProperty(data,key,{
                get(){
                    return value 
                },
                set(val){
                    value = val
                    setData()
                }
            })
        }
    }

    observe(data)
    setData()

</script>

3. 监听复杂数据类型响应式

我们只需要判断当前的参数是否是对象 如果是对象利用一下递归。

<script>    

    let data = {
        username:'奥特曼',
        age:18,
        student:{
            name :'怪兽'
        }
    }

    function setData() {
        username.innerHTML = data.username
        age.innerHTML = data.age
        monster.innerHTML = data.student.name
    }

    function observe(data) {
        for (const key in data) {
            if(typeof data[key] == 'object') {
               observe(data[key])
            }
            let value = data[key]
            Object.defineProperty(data,key,{
                get(){
                    return value 
                },
                set(val){
                    value = val
                    setData()
                }
            })
        }
    }

    observe(data)
    setData()

</script>

4.新增对象属性和数组下标修改

在vue中,我们是检测不到一个对象新增属性和直接修改数组某一项的变化,但是上面的代码中是能够对数组下标进行修改的,那为什么vue不可以呢?

 尤大大也说考虑到了性能和用户体验的问题 如果一个数组10000条数据 监听这每一项的数据变化 确实也有很大的性能问题,但vue也提供了解决方案 $set

贴一下 修改数组下标 及 修改不了新增的对象属性代码

<script>    
    let data = {
        username:'奥特曼',
        age:18,
        student:{
            name :'怪兽'
        },
        arr:[0,1,2,3]
    }

    function setData() {
        username.innerHTML = data.username
        age.innerHTML = data.age
        monster.innerHTML = data.student.name
        // 无法对新增的属性进行监听  原因就是observe  一开始就对原数据进行数据的监听  这也是object.defineproperty的本身缺陷
        monsterAge.innerHTML = data.student.age
        number.innerHTML = data.arr[0]
    }

    function observe(data) {
        for (const key in data) {
            if(typeof data[key] == 'object') {
                observe(data[key])
            }
            let value = data[key]
            Object.defineProperty(data,key,{
                get(){
                    return value 
                },
                set(val){
                    value = val
                    setData()
                }
            })
        }
    }

    observe(data)
    setData()

</script>

补充:但是有一点哈,有时候呢 你是可以修改数组某一项实现响应式的,什么时候呢看下面的例子

    <div>
        <div> {{arr[0]}}</div>
        {{ obj.a }}
        <button @click="editNumber">要修改了</button>
    </div>

<script>
export default {
  data () {
    return {
      arr: [0, 1, 2, 3, 4, 5],
      obj: { a: 1 }
    }
  },
  methods: {
    editNumber () {
      this.arr[0] = 999
      // 如果不加下面这一行代码,视图就不会更新
      // 更新的原因:下面的数据是响应式的数据他会去更新视图,一旦更新视图 数据是对整个组件进行更新的,所以arr[0] 会更新
      // 其实底层的object.defineProperty 可以对数组进行更新 但是尤大考虑到数组 的性能与用户体验不成正比 去掉了对数组的响应式 (获取涉及几万条数组非常的大)
      this.obj.a = 2
    }
  }
}
</script>

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

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

相关文章

基于微信小程序的懒人美食帮小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.…

graalvm把springboot 3.0应用编译为原生应用

文章目录1、GraalVM Native Support依赖2、编译为原生应用2.1、编译为docker镜像2.2、编译为原生应用文件之前的文章《Graalvm 安装和静态编译&#xff08;https://blog.csdn.net/penngo/article/details/128006244&#xff09;》介绍了graalvm的安装和环境配置&#xff0c;普通…

【Rust】6. 结构体与方法

6.1 结构体的定义和实例化 6.1.1 结构体定义、创建实例 6.1.2 创建实例&#xff1a;字段初始化简写语法 6.1.3 创建实例&#xff1a;结构体更新语法&#xff08;注意&#xff1a;数据的移动特性&#xff01;&#xff09; .. 语法&#xff1a;指定了剩余未显式设置值的字段应有…

通信原理笔记—差分脉冲编码调制

目录 差分脉冲编码调制(DPCM)&#xff1a; 预测编码&#xff1a; 预测编码的基本原理: 信号预测的基本方法: ΔPCM与DPCM的主要区别: 差分脉冲编码调制(DPCM)&#xff1a; 实际信源的特点&#xff1a;实际信源大都是有记忆的信源&#xff1a;信源的相邻输出符号间(如&…

无广告,小体积,实用性拉满的5款软件

人类与99%的动物之间最大差别在于是否会运用工具&#xff0c;借助好的工具&#xff0c;能提升几倍的工作效率。 1. 无损放大图片——Bigjpg 大杀器&#xff01;深度卷积神经网络实现噪点和锯齿部分补充&#xff0c;从而达到图片无损放大。图片边缘也不会有毛刺和重影,。更重要…

(深度学习快速入门)第四章第二节:什么是卷积神经网络

文章目录一&#xff1a;为什么DNN不适合图像处理&#xff08;1&#xff09;图像的空间信息被丢失&#xff08;不具备空间不变性&#xff09;&#xff08;2&#xff09;参数爆炸二&#xff1a;什么是卷积神经网络三&#xff1a;CNN应用一&#xff1a;为什么DNN不适合图像处理 &…

【关于PostgreSQL的系统信息函数的OID】

一、自带的OID的相关脚本 在PostgreSQL的安装包的src/include/catalog目录下&#xff0c;有着两个脚本&#xff0c;unused_oids和 duplicate_oids。通过这两个可执行脚本&#xff0c;可以查看当前源码包配置里的符合要求的OID。unused_oids可以查看若根据当前源码包初始化产生…

YOLOv5训练结果性能分析

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 可参照以下博客一起看&#xff08;涉及一些概念解析&#xff09;深度学习之常用模型评估指标&#xff08;一&#xff09;—— 分类…

Python大数据处理利器,PySpark的入门实战

PySpark极速入门 一&#xff1a;Pyspark简介与安装 什么是Pyspark&#xff1f; PySpark是Spark的Python语言接口&#xff0c;通过它&#xff0c;可以使用Python API编写Spark应用程序&#xff0c;目前支持绝大多数Spark功能。目前Spark官方在其支持的所有语言中&#xff0c;…

OpenCV-Python学习(18)—— OpenCV 图像几何变换之图像平移(cv.warpAffine)

1. 学习目标 学习图像的平移矩阵&#xff1b;学习 OpenCV 图像平移函数。 2. 图像的平移矩阵 平移是物体位置在水平和垂直方向的移动。 像素点 (x,y) 沿 x 轴平移 dx、沿 y 轴平移 dy&#xff0c;公式&#xff1a; 3. 图像平移函数 3.1 cv.warpAffine() 函数使用 cv.war…

R语言生物群落(生态)数据统计分析与绘图

包含&#xff1a;《R语言基础》、《tidyverse数据清洗》、《多元统计分析》、《随机森林模型》、《回归及混合效应模型》、《结构方程模型》、《统计结果作图》七合一版本 R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂&#…

手动启动Oracle服务和Oracle监听服务和init.ora文件相关

Oracle 11g 安装未完全成功&#xff1b;安装完以后&#xff0c;服务只有2个&#xff1b;这样是用不了&#xff0c;oracle服务和oracle监听服务都没有&#xff1b; 尝试启动一下数据库&#xff0c;出现12560错误&#xff1b; 根据资料&#xff0c;可用如下命令启动Oracle服务&am…

【06】FreeRTOS临界段代码保护及调度器挂起与恢复

目录 1.临界段代码保护简介 2.临界段代码保护函数介绍 2.1任务级临界区调用格式示例 2.2中断级临界区调用格式示例 2.3函数调用特点 2.4任务级进入和退出临界段函数 2.5中断级进入和退出临界段函数 3.任务调度器的挂起和恢复 3.1任务调度器挂起函数vTaskSuspendAll() …

为什么大部分虚拟主机都配置SSD

对于任何站长来说&#xff0c;拥有一个不会加载的漂亮网站可能是毁灭性的。选择正确的托管服务对于确保网站始终以最佳状态运行至关重要。而由于新手站长呈爆发性增长态势&#xff0c;选择虚拟主机的站长日趋增多。本文就将介绍大部分虚拟主机都配置SSD的原因。SSD优势SSD在数据…

Windows下MySQL5与MySQL8的下载、安装、配置

MySQL版本简介 MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;自由下载&#xff0c;但不提供官方技术支持&#xff0c;适用于 大多数普通用户。MySQL Enterprise Edition 企业版本&#xff0c;需付费&#xff0c;不能在线下载&#xff0c;可以试用30天。提供…

EMT4J详细介绍与使用,帮你找到Java版本升级带来的问题,让你在项目jdk升级不在头疼

Java版本升级带来的问题 前因 java更新迭代速度巨快无比&#xff0c;Spring Framework 6 等项目已经至少需要 Java 17。但是&#xff0c;对于 Java 版本的采用是相对缓慢的。例如&#xff0c;在 Java 11 发布四年之后&#xff08;2022年&#xff09;&#xff0c;只有不到 49%…

[C语言]操作符

目录 1.操作符分类 2.算术操作符 3.位移操作符 3.1左移操作符 3.2右移操作符 4.位操作符 4.1’&‘&#xff08;按位与&#xff09; 4.2’|‘&#xff08;按位或&#xff09; 4.3‘^’&#xff08;按位异或&#xff09; 5.赋值操作符 5.1复合赋值符 6.单目操作…

IDEA搭建Finchley.SR2版本的SpringCloud父子基础项目-------Hystrix断路器

1.1分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系&#xff0c;每个依赖关系在某些时候将不可避免地失败。 服务雪崩 多个微服务之间调用的时候&#xff0c;假设微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其它的微服务&#xff0…

高薪前端都应该具备的开发好习惯

格拉德威尔曾提出过一个“一万小时定律”&#xff0c;即任何人从平凡到大师的必要条件&#xff0c;就是历经1万小时的锤炼&#xff0c;而这“1万小时”也不是达到就行&#xff1b;如何构成&#xff0c;才是能否成为行业资深的关键。总结起来&#xff0c;就是四个字&#xff1a;…

Databend 开源周报 第 77 期

Databend 是一款强大的云数仓。专为弹性和高效设计。自由且开源。 即刻体验云服务&#xff1a;https://app.databend.com 。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements Meta 使用 expressin::TableSch…