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]
    })
  }
}
相关推荐
workflower1 小时前
单元测试-例子
java·开发语言·算法·django·个人开发·结对编程
YuanlongWang1 小时前
C# 基础——装箱和拆箱
java·开发语言·c#
b78gb1 小时前
电商秒杀系统设计 Java+MySQL实现高并发库存管理与订单处理
java·开发语言·mysql
Y42582 小时前
本地多语言切换具体操作代码
前端·javascript·vue.js
LXS_3573 小时前
Day 05 C++ 入门 之 指针
开发语言·c++·笔记·学习方法·改行学it
fruge3 小时前
React 2025 完全指南:核心原理、实战技巧与性能优化
javascript·react.js·性能优化
速易达网络4 小时前
Bootstrap 5 响应式网站首页模板
前端·bootstrap·html
etsuyou4 小时前
js前端this指向规则
开发语言·前端·javascript
lichong9514 小时前
Android studio 修改包名
android·java·前端·ide·android studio·大前端·大前端++
cai_huaer4 小时前
BugKu Web渗透之 cookiesWEB
前端·web安全