Day 05- Vue3 Vue2响应式原理

news2024/11/24 11:35:29

Vue2的响应式

核心:通过 Object.defineProtytype() 对对象的已有属性值的读取和修改进行劫持; 

数据劫持  --> 给对象扩展属性 -->  属性设置

  • 实现原理:

    • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

    • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

      • 比如说在 vue2 中,data 数据中有一个数组, 当我们调用data 数组中的push方法,我们调用的是经过二次封装的push, 和 array原型中的push 方法不是一个事;

      • 被封装的 push  方法中主要做了两件事:

        • 帮们正常调用数据的push方法

        • 帮我们更新界面 ; 

  • 存在问题:

    • 新增属性、删除属性, 界面不会更新。

    • 直接通过下标修改数组, 界面不会自动更新。

Vue2框架中数据响应式的优缺点 

<template>
    <div>
        <h1>我是Vue2写的效果</h1>
        <h2 v-show="person.name">姓名: {{fperson.name}}</h2>
        <h2 v-show="person.sex">性别: {{person.sex}} </h2>
        <h2>年龄: {{ person.age }} </h2>
        <h2>爱好: {{ person.hobby}} </h2>
        <button @click="addSex">添加一个sex属性</button>
        <button @click="deleteName">删除name属性</button>
        <button @click="updateHobby">修改第一个爱好的名字</button>
    </div>
</template>
    <script>
    import Vue from 'vue'
    export default {
        name:'App'
        data() {
           return {
              person:{
                  name:'张三',
                  age:18,
                  hobby: ["学习", "吃饭"]
              }
           }
        }
        methods: {
         // 新增属性、删除属性, 界面不会更新
         // 添加对象属性 
         addSex() {
            // 数据改变页面没有监听到! 
            this.person.sex = '女'
            // 解决方式: $set() 给对象追加一个响应式数据 
            this.$set(this.person, 'sex', '女')
            Vue.set(this.person, 'sex', '女')  
         }

        // 删除对象属性 
        deleteName(){
            // delete this.person.name
            // 移除一个响应式数据 
            this.$delete(this.person, name)
            Vue.delete(this.person, 'name', '女')
        }
        // 直接通过下标修改数组, 界面不会自动更新。
        updateHobby() {
            // this.person.hobby[0] = '逛街'
            this.$set(this.person.hobby, 0, '逛街')
            // 调用 Array 中的变更方法可以实现修改
            this.person.hobby.splice(0, 1, '逛街')
        }
    } 
    </script>
}

Vue2数据响应式原理 

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

语法https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#%E8%AF%AD%E6%B3%95

Object.defineProperty(obj, prop, descriptor)
  1. obj: 要定义属性的对象。
  2. prop: 要定义或修改的属性的名称或 Symbol 。
  3. descriptor: 要定义或修改的属性描述符。
  4. 返回值: 被传递给函数的对象。
function defineProperty () {
  var _obj = {}
 
  Object.defineProperty(_obj, 'a', {
    value: 1
  })
  return _obj
}
 
var obj = defineProperty()
console.log(obj);  //{a:1}

第三个参数里面还有6个配置控住属性

  1.     writable:是否可重写
  2.     value:    当前值
  3.     get:        读取时内部调用的函数
  4.     set:        写入时内部调用的函数
  5.     enumerable:是否可以遍历
  6.     configurable: 是否可再次修改配置项
<body>
    <script type="text/javascript">
        // 源数据
        let person = {
            name: '张三', 
            age: 18
        }

        // 模拟vue2中实现响应式 
        let p = {} 
        
        // p 对象身上追加响应式数据 
        Object.defineProperty(p, 'name', {
            // 可配置的, 配置删除使用 
            configurable: true, 
            get() { // 有人读取name时调用 
                return person.name
            },
            set(value) { // 有人修改name时调用 
                console.log('有人修改了name属性, 我发现了, 我要去更新页面!');
                person.name = value
            }
        })

        Object.defineProperty(p, 'age', {
            configurable: true,
                
            value:"男",       //设置属性值
            enumerable:true,  //控制属性是否可以枚举,默认值是false
            writable:true,    //控制属性是否可以被修改、可写,默认值是false
            configurable:true //控制属性是否可以被删除、可配置,默认值是false

            get() { // 有人读取age时调用 
                return person.age
            },
            set(value) { // 有人修改age时调用 
                console.log('有人修改了age属性, 我发现了, 我要去更新页面!');
                person.age = value
            }
        })
        
        // 数据修改
        // p.age = 20     -- 有人修改了age属性, 我发现了, 我要去更新页面!
        // 数据删除 
        // delete p.name  --  true 主要需要 configurable: true 
        // 属性添加; 但是不是响应式的没有 set get 方法; 
        // p.sex = '男'


    </script>
</body>

writable:true           控制属性是否可以被修改,控制台也看的当为TRUE的时候属性值可以被修改
configurable:true      控制属性是否可以被删除
enumerable:true      控制属性是否可以枚举,true的话简单的说就是可以遍历获取该值

还有最重要的两个属性 set和get(即存取器描述:定义属性如何被存取),这两个属性是干嘛的?

注意:当使用了getter或setter方法,不允许使用writable和value这两个属性(如果使用,会直接报错滴)

  get 是获取值的时候的方法,类型为 function ,获取值的时候会被调用,不设置时为undefined

  set 是设置值的时候的方法,类型为 function ,设置值的时候会被调用,undefined

  get或set不是必须成对出现,任写其一就可以

get:

        当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值

        每一次获取属性值时,都会先走get方法,我们可以在返回该属性值之前,做一些事情;

set:

        当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值

        每一次改变属性值时,都会先走set方法,相应的,我们也可以在这里做一些事情;

可以实现一个数据的联动效果

Vue3.0的响应式

  • 实现原理:

    • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。

    • 通过Reflect(反射): 对源对象的属性进行操作。

    • MDN文档中描述的Proxy与Reflect:

      • Proxy:Proxy - JavaScript | MDN

      • Reflect:Reflect - JavaScript | MDN

new Proxy(data, {
	// 拦截读取属性值
    get (target, prop) {
    	return Reflect.get(target, prop)
    },
    // 拦截设置属性值或添加新属性
    set (target, prop, value) {
    	return Reflect.set(target, prop, value)
    },
    // 拦截删除属性
    deleteProperty (target, prop) {
    	return Reflect.deleteProperty(target, prop)
    }
})

proxy.name = 'tom'   

Vue3响应式原理_Proxy

<body>
    <script>
         // 源数据
         let person = {
            name: '张三', 
            age: 18
        }
        //模拟 Vue3中实现数据响应式 
        // 定义一个代理对象p;  让p去映射对person的操作, 能检测到变化!
        const p = new Proxy(person, {
            // 完成数据的响应式, 捕获数据的修改
            get(target, propName) {// 获取读取 target: 源数据; propName: 读取修改的属性 
                console.log(`有人读取了 p 身上的${ propName }属性!`);
                return target[propName]
            },
            set(target, propName, value) { // 修改,追加调用 
                console.log(`有人修改了 p 身上的${ propName }属性, 我要去更新页面了!`);
                target[propName] = value
            },
            deleteProperty(target, propName) { // 删除调用  target: 要删除的源数据;  propName: 删除属性 
                console.log(`有人删除了 p 身上的${ propName }属性, 我要去更新页面了!`);
                return delete target[propName]
            }
        })

        // p.sex ="男"      添加属性 
        // delete p.age     true 删除属性 
        // p.name = "ls"    有人修改了 p 身上的name属性, 我要求修改页面了!
        // delete p.age     有人删除了 p 身上的age属性, 我要去更新页面了!
        // p.sex ='男'      有人修改了 p 身上的sex属性, 我要去更新页面了!
    </script>
</body>

最后总结:

1、defineProperty是对一个空对象进行设置属性,在读取和改变属性值的拦截一下,可以实现一些其他的逻辑处理。不支持函数拦截;

2、Proxy是对一个完整的对象进行代理,相当于拷贝了一份,当我们对原数据进行属性值操作时,这个代理对象会挡在前面对数据进行操作。支持对象代理,数组代理和函数代理。
 

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

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

相关文章

风控黑名单库的使用与判断指南

反欺诈策略中有一类策略是专门针对黑名单用户的&#xff0c;我们称之为黑名单命中策略。 一、黑名单定义 黑名单是对严重逾期、骗贷、失联、诈骗等系列高风险客群构建的名单&#xff0c;即为明确非意向客群的名单。黑名单也是反欺诈的第一道防线&#xff0c;可以有效识别黑产客…

近些年大火的零信任,落地情况怎么样?

疫情以来      居家办公、远程工作需求激增      企业IT环境变得更加复杂      在此背景下      以“持续验证,永不信任”为核心的      零信任火爆出圈      引得国内外企业机构纷纷布局      然而根据戴尔2022全球数据保护指数(GDPI),尽管91%的组…

使用FFmpeg+go搭建m3u8点播服务器

一. 前言 HLS&#xff08;HTTP Live Streaming&#xff09; 是苹果公司提出的基于 HTTP 的流媒体传输协议&#xff0c;它的工作原理是将整个文件切分成一个个小的文件&#xff08;通常是 TS 格式文件&#xff09;&#xff0c;客户端通过 HTTP 下载播放。在准备播放某个 m3u8 媒…

Linux系统运行时参数命令--Linux基础命令和工具

目录 1 Linux基础命令和工具 1.1 grep搜索字符 1.2 find查找文件 1.3 ls显示文件 1.4 wc命令 1.5 ulimit用户资源 1.6 scp远程拷贝 1.7 dos2unix和unix2dos 1.8 sed 行处理 简单模式 替换模式 1.9 awk 列处理 C/CLinux服务器开发/后台架构师【零声教育】-学习视频…

车载软件架构—CP和AP相同与不同

文章目录 前言一、两者不同之处二、两者架构设计原则总结前言 AUTOSAR(AUTmotive Open System ARchitecture) 是汽车电子E/E系统发展的一个重要的节点。该标准是由包括BMW、DAIMLER、GM、TOYOTA、福特等主机厂和包括博世、大陆等供应商牵头成立的一个标准发展组织定义的一个开…

45页智慧交通数字化解决方案2022

【版权声明】本资料来源网络&#xff0c;仅用于行业知识分享&#xff0c;供个人学习参考&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间进行删除&#xff01; 完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 项目建设目标…

RabbitMQ简单模式

&#x1f341;博客主页&#xff1a;&#x1f449;不会压弯的小飞侠 ✨欢迎关注&#xff1a;&#x1f449;点赞&#x1f44d;收藏⭐留言✒ ✨系列专栏&#xff1a;&#x1f449;Linux专栏 &#x1f525;欢迎大佬指正&#xff0c;一起学习&#xff01;一起加油&#xff01; 目录&…

20 个常用的 pandas 使用技巧

大家好&#xff0c;我是小寒。 今天来分享 20 个常用的 pandas 使用技巧。如果觉得不错&#xff0c;点赞、转发安排起来。 1、以 Markdown 格式输出 DataFrame import pandas as pddf pd.DataFrame({a: [1, 2, 3, 4],b: [5, 6, 7, 8]})# You can control the printing of th…

ATAC-seq分析:教程简介(1)

简介 本课程[1]介绍 Bioconductor 中的 ATACseq 分析。 该课程由 2 个部分组成。这将引导您完成正常 ATACseq 分析工作流程的每个步骤。它涵盖比对、QC、peak calling、基因组富集测试、基序富集和差异可及性测试。 环境准备 IGV IGV 可以从 BROAD 网站安装。 》 https://www.b…

mysql实现行转列作为临时表、以及字符分割行转列

1.需求&#xff1a;实现两个日期段转换为具体的日期天数&#xff08;2022-10-23至2022-10-26得到一张2022-10-23、2022-10-24、2022-10-25、2022-10-26的临时表&#xff09; SELECTDATE_FORMAT( DATE_ADD( 2022-10-23 22:00:00, INTERVAL ( help_topic_id ) DAY ), %Y-%m-%d …

微服务洞察,让微服务更透明

作者&#xff1a; 屿山 微服务作为云原生时代下一种开发软件的架构和组织方法&#xff0c;通过将明确定义的功能分成更小的服务&#xff0c;并让每个服务独立迭代&#xff0c;增加了应用程序的灵活性&#xff0c;允许开发者根据需要更轻松地更改部分应用程序。同时每个微服务可…

想不起来的python知识点(应该后续还会再补充)

目录数据类型Number随机生成一个[0,1)范围的实数随机生成一个[1,20)范围内的整数补String(字符串)字符串连接使用join运算符List&#xff08;列表&#xff09;由于没有书&#xff0c;利用博客对于Python的学习内容进行简要的记录&#xff01;&#xff08;应该是菁&#xff08;j…

基于声网 Flat 构建白板插件应用“成语解谜”的最佳实践

前言 本文作者赵杭天。他参加了“2022 RTE 编程挑战赛”——“赛道二 场景化白板插件应用开发” &#xff0c; 并凭借作品“成语解谜”获得了该赛道大奖。“成语解谜”是一个基于互动白板 SDK 的互动小游戏应用。通过前端编码、调用白板 API 能力、定制化后端逻辑等&#xff0…

刷题记录:牛客NC17509挖沟[prim+kruskal算法详解]

传送门:牛客 题目描述: 胡队长带领HA实验的战士们玩真人CS&#xff0c;真人CS的地图由一些据点组成&#xff0c;现在胡队长已经占领了n个据点&#xff0c;为了方 便&#xff0c;将他们编号为1-n&#xff0c;为了隐蔽&#xff0c;胡队长命令战士们在每个据点出挖一个坑&#x…

Cocos Creator 3.61所有工具软件的使用

文章目录Tiled-地图绘制软件下载安装基本使用点点就会了导入cocos编辑动画注意cocos导入TiledBigShear-图片裁剪为plist形式下载安装使用TexturePacker-使用plist文件产生精灵图集下载安装Tiled-地图绘制软件 下载安装 官网免费 Tiled官方 安装无要求 基本使用 点点就会了 导…

UE5 Meerkat狐獴演示Demo分析

1.特效的生成方式 1.1临时特效的生成&#xff1a;使用了已生成轨道临时创建该特效&#xff08;不用在场景中放入该特效&#xff0c;而是临时创建即可&#xff09;、系统生命周期轨道设置该特效的播放时长 1.2长期特效的生成&#xff1a;特效时长为该镜头片段长度 2.特效的类…

软考高级哪个好考?

软考高级有5个科目。 开发方向的有系统分析师&#xff0c;系统架构师&#xff1b; 网络方向的有网络规划与设计师&#xff1b; 信息系统方向的有信息系统项目管理师&#xff1b; 信息化服务方向的有系统规划与管理师。 考试题型 上午是9:00 — 11:30考综合知识&#xff0c;…

ROBOGUIDE软件:FANUC机器人多层堆焊功能介绍与示教编程操作方法

目录 机器人多层堆焊功能介绍 机器人跟踪路径数据指令介绍 机器人多层堆焊指令介绍 机器人弧焊焊接工作站创建 机器人多层堆焊示教编程 仿真运行 机器人多层堆焊功能介绍 在厚板焊接中进行多层堆焊焊接&#xff0c;以便多次焊接相同的部位而增大焊接宽度。通常情况下&am…

Java池化技术

在我们平常的编码中&#xff0c;通常会将一些对象保存起来&#xff0c;这主要考虑的是对象的创建成本。比如像线程资源、数据库连接资源或者 TCP 连接等&#xff0c;这类对象的初始化通常要花费比较长的时间&#xff0c;如果频繁地申请和销毁&#xff0c;就会耗费大量的系统资源…

Java-String 类·上

Java-String 类上1. 创建字符串2. 字符串比较相等3. 字符串常量池4. 理解字符串不可变大家好&#xff0c;我是晓星航。今天为大家带来的是Java String字符串相关知识点的讲解&#xff01;&#x1f600; 1. 创建字符串 常见的构造 String 的方式 // 方式一 String str "…