vue2响应式原理,数据劫持,数据代理,Object.defineProperty()方法

数据代理、数据劫持概念

数据劫持

data中数据通过各种逻辑和封装变成_data,从而去监测data数据的变化,一旦发现data中数据变化了,_data就去修改页面,这个过程通过Object.defineProperty实现,叫数据劫持

数据代理

_data中数据拿出放在vm身上,就可以直接通过vm.name,不需要vm._data.name 通过Object.defineProperty()实现,这个过程叫数据代理

Object.defineProperty()方法

  • es5新增的一个方法
  • 作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

语法:

js 复制代码
 Object.defineProperty(obj,prop,desc)
// obj:在哪个对象身上添加或者修改属性
// prop:添加或修改的属性名
// desc:配置项,一般是一个对象
/* 
  desc 配置项还有6个配置属性
  value: "jack",  给属性添加指定属性值
  writable: true, 默认false不可以修改,true属性可以被修改
  enumerable: true, 默认false不可以遍历,true可以被遍历
  configurable: true, 默认false不能删除,true可以被删除
  get(){}, 当读取属性值的时候,getter就会被调用,函数的返回值会作为该属性的值
  set(){}, 当修改属性值的时候,getter就会被调用,该方法将接受唯一参数,即该属性新的参数值
*/

注意:

  1. 当使用了 getter 或 setter 方法,不允许使用 writable 和 value这两个属性
  2. 不要在 gette r中再次获取该属性值,也不要在 setter 中再次设置该属性,否则会栈溢出

示例:

js 复制代码
  let  person = {
  name:"码农",
  age: 18
     }
     Object.defineProperty(person,'sex',{
         value:"男",  //设置属性值
         enumerable:true, //控制属性是否可以枚举,默认值是false
         writable:true, //控制属性是否可以被修改,默认值是false
         configurable:true //控制属性是否可以被删除,默认值是false
      })
    console.log(person)

数据代理

数据代理的概念

数据代理(Data Proxy):

  • 通过访问代理对象的属性,来间接访问目标对象的属性
  • 在 Vue 中,将data 对象中的属性代理到 Vue 的实例上
  • 这样一来,我们可以通过直接访问 Vue 实例来访问和修改其data对象的属性(这就是为什么直接Vue的实例 . 就可以访问到属性以及方法的底层原理)
  • 更加方便的操作data中的数据

Vue数据代理对属性名的要求

  • data对象的属性名不可以以 " _ "或 " $ " 开头,
  • 因为Vue的实例上的属性名以 " _ " 或 " $ " 开头,会产生冲突

数据劫持

数据劫持(Data Interception):

  • 数据劫持是指在访问或修改对象的属性时,对这些操作进行拦截和监视,以便在属性发生变化时能够触发相关的操作。
  • 在 Vue 中,数据劫持用于监听数据的变化,以实现双向绑定和响应式更新
  • Vue 通过在数据对象的属性上使用 Object.defineProperty 来实现数据劫持
  • 每当访问属性或修改属性时,Vue 会触发相应的 getset 拦截器,从而实现对数据变化的监听
  • 通过数据劫持,Vue 能够在属性发生变化时自动触发视图的更新,从而实现了响应式的特性

Vue数据代理、数据劫持底层实现

html 代码部分

html 复制代码
  <script src='./myVue.js'></script>
  <div id ="root"></div>
  <script>
   let vm = new MyVue({
    el: '#root',
    data(){
       return{
        name: '张三',
        age:18
       }
      },
     methods: {
       fn(){
        console.log('我是方法');
       }
     }
   });
  </script>

js 代码部分

js 复制代码
class MyVue {
  //简单实现数据代理
  constructor(options) {
    Object.keys(options.data()).forEach((item, index) => {
      Object.defineProperty(this, item, {
        get() {
          console.log('读取了数据',item);
          return options.data()[item]
        },
        set(value) {
          console.log('修改了数据',item,value);
          options.data()[item] = value
        }
      })
    })
    // 简单实现methods
    Object.keys(options.methods).forEach(item =>{
      this[item] = options.methods[item]
    })
  }
}
相关推荐
huashengzsj几秒前
Shopify个人建站如何搭建独立站:从零开始的完整指南
前端·网络·人工智能
木木子228 分钟前
[特殊字符] 音乐播放器——状态驱动的多媒体控制
android·开发语言·华为·php·harmonyos
程序猿小泓11 分钟前
从 Claude Code 学 Agent Harness:一个前端工程师的 AI Agent 学习笔记
前端·人工智能·学习
六个九十度1 小时前
用python脚本访问被网关隔离的嵌入式设备
开发语言·python
柒和远方1 小时前
从审计日志到可下载证据包:事务型 Outbox、租约 fencing 与保留水位
前端·后端·架构
酷酷的身影1 小时前
Drivers/LedManager.cs
开发语言·php
卓怡学长1 小时前
w266基于spring boot + vue 圣地延安美食乐享系统
java·数据库·vue.js·spring boot·spring·intellij-idea
小樱花的樱花1 小时前
Linux 线程的创建
linux·c语言·开发语言
minglie11 小时前
npm ali-oss库依赖冲突
前端·npm
xiaoshuaishuai81 小时前
C# AI实现PR处理、单元测试
开发语言·c#·log4j